diff --git a/src/rpc/abc.cpp b/src/rpc/abc.cpp --- a/src/rpc/abc.cpp +++ b/src/rpc/abc.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -14,8 +15,9 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 0) { throw std::runtime_error( - "getexcessiveblock\n" - "\nReturn the excessive block size." + RPCHelpMan{ + "getexcessiveblock", "\nReturn the excessive block size.", {}} + .ToString() + "\nResult\n" " excessiveBlockSize (integer) block size in bytes\n" "\nExamples:\n" + @@ -32,10 +34,15 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 1) { throw std::runtime_error( - "setexcessiveblock blockSize\n" - "\nSet the excessive block size. Excessive blocks will not be used " - "in the active chain or relayed. This discourages the propagation " - "of blocks that you consider excessively large." + RPCHelpMan{ + "setexcessiveblock", + "\nSet the excessive block size. Excessive blocks will not be " + "used in the active chain or relayed. This discourages the " + "propagation of blocks that you consider excessively large.", + { + {"blockSize", RPCArg::Type::NUM, false}, + }} + .ToString() + "\nArguments\n" "1. blockSize (integer, required) Excessive block size in bytes. " "Must be greater than " + diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -155,8 +155,11 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 0) { throw std::runtime_error( - "getblockcount\n" - "\nReturns the number of blocks in the longest blockchain.\n" + RPCHelpMan{ + "getblockcount", + "\nReturns the number of blocks in the longest blockchain.\n", + {}} + .ToString() + "\nResult:\n" "n (numeric) The current block count\n" "\nExamples:\n" + @@ -172,9 +175,11 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 0) { throw std::runtime_error( - "getbestblockhash\n" - "\nReturns the hash of the best (tip) block in the " - "longest blockchain.\n" + RPCHelpMan{"getbestblockhash", + "\nReturns the hash of the best (tip) block in the " + "longest blockchain.\n", + {}} + .ToString() + "\nResult:\n" "\"hex\" (string) the block hash hex-encoded\n" "\nExamples:\n" + @@ -190,8 +195,10 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 0) { throw std::runtime_error( - "getfinalizedblockhash\n" - "\nReturns the hash of the currently finalized block\n" + RPCHelpMan{"getfinalizedblockhash", + "\nReturns the hash of the currently finalized block\n", + {}} + .ToString() + "\nResult:\n" "\"hex\" (string) the block hash hex-encoded\n"); } @@ -217,10 +224,14 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() > 1) { throw std::runtime_error( - "waitfornewblock (timeout)\n" - "\nWaits for a specific new block and returns " - "useful info about it.\n" - "\nReturns the current block on timeout or exit.\n" + RPCHelpMan{"waitfornewblock", + "\nWaits for a specific new block and returns useful " + "info about it.\n" + "\nReturns the current block on timeout or exit.\n", + { + {"timeout", RPCArg::Type::NUM, true}, + }} + .ToString() + "\nArguments:\n" "1. timeout (int, optional, default=0) Time in " "milliseconds to wait for a response. 0 indicates " @@ -269,10 +280,15 @@ if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { throw std::runtime_error( - "waitforblock (timeout)\n" - "\nWaits for a specific new block and returns useful info about " - "it.\n" - "\nReturns the current block on timeout or exit.\n" + RPCHelpMan{"waitforblock", + "\nWaits for a specific new block and returns useful " + "info about it.\n" + "\nReturns the current block on timeout or exit.\n", + { + {"blockhash", RPCArg::Type::STR_HEX, false}, + {"timeout", RPCArg::Type::NUM, true}, + }} + .ToString() + "\nArguments:\n" "1. \"blockhash\" (required, string) Block hash to wait for.\n" "2. timeout (int, optional, default=0) Time in milliseconds " @@ -326,11 +342,15 @@ if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { throw std::runtime_error( - "waitforblockheight height ( timeout )\n" - "\nWaits for (at least) block height and returns the height and " - "hash\n" - "of the current tip.\n" - "\nReturns the current block on timeout or exit.\n" + RPCHelpMan{"waitforblockheight", + "\nWaits for (at least) block height and returns the " + "height and hash\nof the current tip.\n" + "\nReturns the current block on timeout or exit.\n", + { + {"height", RPCArg::Type::NUM, false}, + {"timeout", RPCArg::Type::NUM, true}, + }} + .ToString() + "\nArguments:\n" "1. height (int, required) Block height to wait for (int)\n" "2. timeout (int, optional, default=0) Time in milliseconds to " @@ -379,9 +399,12 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() > 0) { throw std::runtime_error( - "syncwithvalidationinterfacequeue\n" - "\nWaits for the validation interface queue to catch up on " - "everything that was there when we entered this function.\n" + RPCHelpMan{ + "syncwithvalidationinterfacequeue", + "\nWaits for the validation interface queue to catch up on " + "everything that was there when we entered this function.\n", + {}} + .ToString() + "\nExamples:\n" + HelpExampleCli("syncwithvalidationinterfacequeue", "") + HelpExampleRpc("syncwithvalidationinterfacequeue", "")); @@ -393,16 +416,19 @@ static UniValue getdifficulty(const Config &config, const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 0) { - throw std::runtime_error("getdifficulty\n" - "\nReturns the proof-of-work difficulty as a " - "multiple of the minimum difficulty.\n" - "\nResult:\n" - "n.nnn (numeric) the proof-of-work " - "difficulty as a multiple of the minimum " - "difficulty.\n" - "\nExamples:\n" + - HelpExampleCli("getdifficulty", "") + - HelpExampleRpc("getdifficulty", "")); + throw std::runtime_error( + RPCHelpMan{"getdifficulty", + "\nReturns the proof-of-work difficulty as a " + "multiple of the minimum difficulty.\n", + {}} + .ToString() + + "\nResult:\n" + "n.nnn (numeric) the proof-of-work " + "difficulty as a multiple of the minimum " + "difficulty.\n" + "\nExamples:\n" + + HelpExampleCli("getdifficulty", "") + + HelpExampleRpc("getdifficulty", "")); } LOCK(cs_main); @@ -535,9 +561,13 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() > 1) { throw std::runtime_error( - "getrawmempool ( verbose )\n" - "\nReturns all transaction ids in memory pool as a json array of " - "string transaction ids.\n" + RPCHelpMan{"getrawmempool", + "\nReturns all transaction ids in memory pool as a json " + "array of string transaction ids.\n", + { + {"verbose", RPCArg::Type::BOOL, true}, + }} + .ToString() + "\nHint: use getmempoolentry to fetch a specific transaction from " "the mempool.\n" "\nArguments:\n" @@ -572,8 +602,14 @@ if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { throw std::runtime_error( - "getmempoolancestors txid ( verbose )\n" - "\nIf txid is in the mempool, returns all in-mempool ancestors.\n" + RPCHelpMan{"getmempoolancestors", + "\nIf txid is in the mempool, returns all in-mempool " + "ancestors.\n", + { + {"txid", RPCArg::Type::STR_HEX, false}, + {"verbose", RPCArg::Type::BOOL, true}, + }} + .ToString() + "\nArguments:\n" "1. \"txid\" (string, required) The transaction id " "(must be in mempool)\n" @@ -642,8 +678,14 @@ if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { throw std::runtime_error( - "getmempooldescendants txid ( verbose )\n" - "\nIf txid is in the mempool, returns all in-mempool descendants.\n" + RPCHelpMan{"getmempooldescendants", + "\nIf txid is in the mempool, returns all in-mempool " + "descendants.\n", + { + {"txid", RPCArg::Type::STR_HEX, false}, + {"verbose", RPCArg::Type::BOOL, true}, + }} + .ToString() + "\nArguments:\n" "1. \"txid\" (string, required) The transaction id " "(must be in mempool)\n" @@ -710,8 +752,12 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 1) { throw std::runtime_error( - "getmempoolentry txid\n" - "\nReturns mempool data for given transaction\n" + RPCHelpMan{"getmempoolentry", + "\nReturns mempool data for given transaction\n", + { + {"txid", RPCArg::Type::STR_HEX, false}, + }} + .ToString() + "\nArguments:\n" "1. \"txid\" (string, required) " "The transaction id (must be in mempool)\n" @@ -744,8 +790,13 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 1) { throw std::runtime_error( - "getblockhash height\n" - "\nReturns hash of block in best-block-chain at height provided.\n" + RPCHelpMan{"getblockhash", + "\nReturns hash of block in best-block-chain at height " + "provided.\n", + { + {"height", RPCArg::Type::NUM, false}, + }} + .ToString() + "\nArguments:\n" "1. height (numeric, required) The height index\n" "\nResult:\n" @@ -771,11 +822,16 @@ if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { throw std::runtime_error( - "getblockheader \"blockhash\" ( verbose )\n" - "\nIf verbose is false, returns a string that is serialized, " - "hex-encoded data for blockheader 'hash'.\n" - "If verbose is true, returns an Object with information about " - "blockheader .\n" + RPCHelpMan{"getblockheader", + "\nIf verbose is false, returns a string that is " + "serialized, hex-encoded data for blockheader 'hash'.\n" + "If verbose is true, returns an Object with information " + "about blockheader .\n", + { + {"blockhash", RPCArg::Type::STR_HEX, false}, + {"verbose", RPCArg::Type::BOOL, true}, + }} + .ToString() + "\nArguments:\n" "1. \"blockhash\" (string, required) The block hash\n" "2. verbose (boolean, optional, default=true) true for a " @@ -871,13 +927,19 @@ if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { throw std::runtime_error( - "getblock \"blockhash\" ( verbosity )\n" - "\nIf verbosity is 0 or false, returns a string that is " - "serialized, hex-encoded data for block 'hash'.\n" - "If verbosity is 1 or true, returns an Object with information " - "about block .\n" - "If verbosity is 2, returns an Object with information about block " - " and information about each transaction.\n" + RPCHelpMan{ + "getblock", + "\nIf verbosity is 0 or false, returns a string that is " + "serialized, hex-encoded data for block 'hash'.\n" + "If verbosity is 1 or true, returns an Object with information " + "about block .\n" + "If verbosity is 2, returns an Object with information about " + "block and information about each transaction.\n", + { + {"blockhash", RPCArg::Type::STR_HEX, false}, + {"verbosity", RPCArg::Type::NUM, true}, + }} + .ToString() + "\nArguments:\n" "1. \"blockhash\" (string, required) The block hash\n" "2. verbosity (numeric, optional, default=1) 0 for " @@ -1046,7 +1108,12 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 1) { throw std::runtime_error( - "pruneblockchain height\n" + RPCHelpMan{"pruneblockchain", + "", + { + {"height", RPCArg::Type::NUM, false}, + }} + .ToString() + "\nArguments:\n" "1. \"height\" (numeric, required) The block height to prune " "up to. May be set to a discrete height, or a unix timestamp\n" @@ -1110,9 +1177,12 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 0) { throw std::runtime_error( - "gettxoutsetinfo\n" - "\nReturns statistics about the unspent transaction output set.\n" - "Note this call may take some time.\n" + RPCHelpMan{"gettxoutsetinfo", + "\nReturns statistics about the unspent transaction " + "output set.\n" + "Note this call may take some time.\n", + {}} + .ToString() + "\nResult:\n" "{\n" " \"height\":n, (numeric) The current block height (index)\n" @@ -1155,8 +1225,15 @@ if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) { throw std::runtime_error( - "gettxout \"txid\" n ( include_mempool )\n" - "\nReturns details about an unspent transaction output.\n" + RPCHelpMan{ + "gettxout", + "\nReturns details about an unspent transaction output.\n", + { + {"txid", RPCArg::Type::STR_HEX, false}, + {"n", RPCArg::Type::NUM, false}, + {"include_mempool", RPCArg::Type::BOOL, true}, + }} + .ToString() + "\nArguments:\n" "1. \"txid\" (string, required) The transaction id\n" "2. \"n\" (numeric, required) vout number\n" @@ -1244,8 +1321,13 @@ int nCheckDepth = gArgs.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS); if (request.fHelp || request.params.size() > 2) { throw std::runtime_error( - "verifychain ( checklevel nblocks )\n" - "\nVerifies blockchain database.\n" + RPCHelpMan{"verifychain", + "\nVerifies blockchain database.\n", + { + {"checklevel", RPCArg::Type::NUM, true}, + {"nblocks", RPCArg::Type::NUM, true}, + }} + .ToString() + "\nArguments:\n" "1. checklevel (numeric, optional, 0-4, default=" + strprintf("%d", nCheckLevel) + @@ -1339,9 +1421,11 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 0) { throw std::runtime_error( - "getblockchaininfo\n" - "Returns an object containing various state info regarding " - "blockchain processing.\n" + RPCHelpMan{"getblockchaininfo", + "Returns an object containing various state info " + "regarding blockchain processing.\n", + {}} + .ToString() + "\nResult:\n" "{\n" " \"chain\": \"xxxx\", (string) current network name " @@ -1444,9 +1528,12 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 0) { throw std::runtime_error( - "getchaintips\n" - "Return information about all known tips in the block tree," - " including the main chain as well as orphaned branches.\n" + RPCHelpMan{ + "getchaintips", + "Return information about all known tips in the block tree, " + "including the main chain as well as orphaned branches.\n", + {}} + .ToString() + "\nResult:\n" "[\n" " {\n" @@ -1584,8 +1671,11 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 0) { throw std::runtime_error( - "getmempoolinfo\n" - "\nReturns details on the active state of the TX memory pool.\n" + RPCHelpMan{"getmempoolinfo", + "\nReturns details on the active state of the TX memory " + "pool.\n", + {}} + .ToString() + "\nResult:\n" "{\n" " \"loaded\": true|false (boolean) True if the mempool is " @@ -1615,12 +1705,17 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 1) { throw std::runtime_error( - "preciousblock \"blockhash\"\n" - "\nTreats a block as if it were received before others with the " - "same work.\n" - "\nA later preciousblock call can override the effect of an " - "earlier one.\n" - "\nThe effects of preciousblock are not retained across restarts.\n" + RPCHelpMan{"preciousblock", + "\nTreats a block as if it were received before others " + "with the same work.\n" + "\nA later preciousblock call can override the effect " + "of an earlier one.\n" + "\nThe effects of preciousblock are not retained across " + "restarts.\n", + { + {"blockhash", RPCArg::Type::STR_HEX, false}, + }} + .ToString() + "\nArguments:\n" "1. \"blockhash\" (string, required) the hash of the block to " "mark as precious\n" @@ -1654,12 +1749,16 @@ UniValue finalizeblock(const Config &config, const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 1) { throw std::runtime_error( - "finalizeblock \"blockhash\"\n" - - "\nTreats a block as final. It cannot be reorged. Any chain\n" - "that does not contain this block is invalid. Used on a less\n" - "work chain, it can effectively PUTS YOU OUT OF CONSENSUS.\n" - "USE WITH CAUTION!\n" + RPCHelpMan{ + "finalizeblock", + "\nTreats a block as final. It cannot be reorged. Any chain\n" + "that does not contain this block is invalid. Used on a less\n" + "work chain, it can effectively PUTS YOU OUT OF CONSENSUS.\n" + "USE WITH CAUTION!\n", + { + {"blockhash", RPCArg::Type::STR_HEX, false}, + }} + .ToString() + "\nResult:\n" "\nExamples:\n" + HelpExampleCli("finalizeblock", "\"blockhash\"") + @@ -1695,9 +1794,13 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 1) { throw std::runtime_error( - "invalidateblock \"blockhash\"\n" - "\nPermanently marks a block as invalid, as if it " - "violated a consensus rule.\n" + RPCHelpMan{"invalidateblock", + "\nPermanently marks a block as invalid, as if it " + "violated a consensus rule.\n", + { + {"blockhash", RPCArg::Type::STR_HEX, false}, + }} + .ToString() + "\nArguments:\n" "1. \"blockhash\" (string, required) the hash of " "the block to mark as invalid\n" @@ -1733,15 +1836,20 @@ UniValue parkblock(const Config &config, const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 1) { - throw std::runtime_error("parkblock \"blockhash\"\n" - "\nMarks a block as parked.\n" - "\nArguments:\n" - "1. \"blockhash\" (string, required) the " - "hash of the block to park\n" - "\nResult:\n" - "\nExamples:\n" + - HelpExampleCli("parkblock", "\"blockhash\"") + - HelpExampleRpc("parkblock", "\"blockhash\"")); + throw std::runtime_error( + RPCHelpMan{"parkblock", + "\nMarks a block as parked.\n", + { + {"blockhash", RPCArg::Type::STR_HEX, false}, + }} + .ToString() + + "\nArguments:\n" + "1. \"blockhash\" (string, required) the " + "hash of the block to park\n" + "\nResult:\n" + "\nExamples:\n" + + HelpExampleCli("parkblock", "\"blockhash\"") + + HelpExampleRpc("parkblock", "\"blockhash\"")); } const std::string strHash = request.params[0].get_str(); @@ -1774,10 +1882,15 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 1) { throw std::runtime_error( - "reconsiderblock \"blockhash\"\n" - "\nRemoves invalidity status of a block and its descendants, " - "reconsider them for activation.\n" - "This can be used to undo the effects of invalidateblock.\n" + RPCHelpMan{ + "reconsiderblock", + "\nRemoves invalidity status of a block and its descendants, " + "reconsider them for activation.\n" + "This can be used to undo the effects of invalidateblock.\n", + { + {"blockhash", RPCArg::Type::STR_HEX, false}, + }} + .ToString() + "\nArguments:\n" "1. \"blockhash\" (string, required) the hash of the block to " "reconsider\n" @@ -1812,10 +1925,14 @@ UniValue unparkblock(const Config &config, const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 1) { throw std::runtime_error( - "unparkblock \"blockhash\"\n" - "\nRemoves parked status of a block and its descendants, " - "reconsider them for activation.\n" - "This can be used to undo the effects of parkblock.\n" + RPCHelpMan{"unparkblock", + "\nRemoves parked status of a block and its " + "descendants, reconsider them for activation.\n" + "This can be used to undo the effects of parkblock.\n", + { + {"blockhash", RPCArg::Type::STR_HEX, false}, + }} + .ToString() + "\nArguments:\n" "1. \"blockhash\" (string, required) the hash of the block to " "unpark\n" @@ -1852,9 +1969,14 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() > 2) { throw std::runtime_error( - "getchaintxstats ( nblocks \"blockhash\" )\n" - "\nCompute statistics about the total number and rate of " - "transactions in the chain.\n" + RPCHelpMan{"getchaintxstats", + "\nCompute statistics about the total number and rate " + "of transactions in the chain.\n", + { + {"nblocks", RPCArg::Type::NUM, true}, + {"blockhash", RPCArg::Type::STR_HEX, true}, + }} + .ToString() + "\nArguments:\n" "1. nblocks (numeric, optional) Size of the window in number " "of blocks (default: one month).\n" @@ -1977,14 +2099,27 @@ if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) { throw std::runtime_error( - "getblockstats hash_or_height ( stats )\n" - "\nCompute per block statistics for a given window. All amounts " - "are in " + - CURRENCY_UNIT + - ".\n" - "It won't work for some heights with pruning.\n" - "It won't work without -txindex for utxo_size_inc, *fee or " - "*feerate stats.\n" + RPCHelpMan{ + "getblockstats", + "\nCompute per block statistics for a given window. All " + "amounts are in " + + CURRENCY_UNIT + + ".\n" + "It won't work for some heights with pruning.\n" + "It won't work without -txindex for utxo_size_inc, *fee or " + "*feerate stats.\n", + { + {"hash_or_height", RPCArg::Type::NUM, false}, + {"stats", + RPCArg::Type::ARR, + { + {"height", RPCArg::Type::STR, true}, + {"time", RPCArg::Type::STR, true}, + }, + true, + "stats"}, + }} + .ToString() + "\nArguments:\n" "1. \"hash_or_height\" (string or numeric, required) The block " "hash or height of the target block\n" @@ -2264,12 +2399,14 @@ static UniValue savemempool(const Config &config, const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 0) { - throw std::runtime_error("savemempool\n" - "\nDumps the mempool to disk. It will fail " - "until the previous dump is fully loaded.\n" - "\nExamples:\n" + - HelpExampleCli("savemempool", "") + - HelpExampleRpc("savemempool", "")); + throw std::runtime_error( + RPCHelpMan{"savemempool", + "\nDumps the mempool to disk. It will fail until the " + "previous dump is fully loaded.\n", + {}} + .ToString() + + "\nExamples:\n" + HelpExampleCli("savemempool", "") + + HelpExampleRpc("savemempool", "")); } if (!::g_mempool.IsLoaded()) { @@ -2355,34 +2492,51 @@ if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { throw std::runtime_error( - "scantxoutset \"action\" [scanobjects,...]\n" - "\nEXPERIMENTAL warning: this call may be removed or changed in " - "future releases.\n" - "\nScans the unspent transaction output set for entries that match " - "certain output descriptors.\n" - "Examples of output descriptors are:\n" - " addr(
) Outputs whose " - "scriptPubKey corresponds to the specified address (does not " - "include P2PK)\n" - " raw() Outputs whose " - "scriptPubKey equals the specified hex scripts\n" - " combo() P2PK and P2PKH outputs " - "for the given pubkey\n" - " pkh() P2PKH outputs for the " - "given pubkey\n" - " sh(multi(,,,...)) P2SH-multisig outputs " - "for the given threshold and pubkeys\n" - "\nIn the above, either refers to a fixed public key in " - "hexadecimal notation, or to an xpub/xprv optionally followed by " - "one\n" - "or more path elements separated by \"/\", and optionally ending " - "in \"/*\" (unhardened), or \"/*'\" or \"/*h\" (hardened) to " - "specify all\n" - "unhardened or hardened child keys.\n" - "In the latter case, a range needs to be specified by below if " - "different from 1000.\n" - "For more information on output descriptors, see the documentation " - "in the doc/descriptors.md file.\n" + RPCHelpMan{"scantxoutset", + "\nEXPERIMENTAL warning: this call may be removed or " + "changed in future releases.\n" + "\nScans the unspent transaction output set for entries " + "that match certain output descriptors.\n" + "Examples of output descriptors are:\n" + " addr(
) Outputs whose " + "scriptPubKey corresponds to the specified address " + "(does not include P2PK)\n" + " raw() Outputs whose " + "scriptPubKey equals the specified hex scripts\n" + " combo() P2PK and " + "P2PKH outputs for the given pubkey\n" + " pkh() P2PKH outputs " + "for the given pubkey\n" + " sh(multi(,,,...)) P2SH-multisig " + "outputs for the given threshold and pubkeys\n" + "\nIn the above, either refers to a fixed " + "public key in hexadecimal notation, or to an xpub/xprv " + "optionally followed by one\n" + "or more path elements separated by \"/\", and " + "optionally ending in \"/*\" (unhardened), or \"/*'\" " + "or \"/*h\" (hardened) to specify all\n" + "unhardened or hardened child keys.\n" + "In the latter case, a range needs to be specified by " + "below if different from 1000.\n" + "For more information on output descriptors, see the " + "documentation in the doc/descriptors.md file.\n", + { + {"action", RPCArg::Type::STR, false}, + {"scanobjects", + RPCArg::Type::ARR, + { + {"descriptor", + RPCArg::Type::OBJ, + { + {"desc", RPCArg::Type::STR, false}, + {"range", RPCArg::Type::NUM, true}, + }, + false, + "scanobjects"}, + }, + false}, + }} + .ToString() + "\nArguments:\n" "1. \"action\" (string, required) The action " "to execute\n" diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -88,13 +88,18 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() > 2) { throw std::runtime_error( - "getnetworkhashps ( nblocks height )\n" - "\nReturns the estimated network hashes per second based on the " - "last n blocks.\n" - "Pass in [blocks] to override # of blocks, -1 specifies since last " - "difficulty change.\n" - "Pass in [height] to estimate the network speed at the time when a " - "certain block was found.\n" + RPCHelpMan{"getnetworkhashps", + "\nReturns the estimated network hashes per second " + "based on the last n blocks.\n" + "Pass in [blocks] to override # of blocks, -1 specifies " + "since last difficulty change.\n" + "Pass in [height] to estimate the network speed at the " + "time when a certain block was found.\n", + { + {"nblocks", RPCArg::Type::NUM, true}, + {"height", RPCArg::Type::NUM, true}, + }} + .ToString() + "\nArguments:\n" "1. nblocks (numeric, optional, default=120) The number of " "blocks, or -1 for blocks since last difficulty change.\n" @@ -185,9 +190,15 @@ if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) { throw std::runtime_error( - "generatetoaddress nblocks address (maxtries)\n" - "\nMine blocks immediately to a specified address (before the RPC " - "call returns)\n" + RPCHelpMan{"generatetoaddress", + "\nMine blocks immediately to a specified address " + "before the RPC call returns)\n", + { + {"nblocks", RPCArg::Type::NUM, false}, + {"address", RPCArg::Type::STR, false}, + {"maxtries", RPCArg::Type::NUM, true}, + }} + .ToString() + "\nArguments:\n" "1. nblocks (numeric, required) How many blocks are generated " "immediately.\n" @@ -226,8 +237,11 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 0) { throw std::runtime_error( - "getmininginfo\n" - "\nReturns a json object containing mining-related information." + RPCHelpMan{"getmininginfo", + "\nReturns a json object containing mining-related " + "information.", + {}} + .ToString() + "\nResult:\n" "{\n" " \"blocks\": nnn, (numeric) The current block\n" @@ -269,9 +283,15 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 3) { throw std::runtime_error( - "prioritisetransaction \"txid\" dummy fee_delta\n" - "Accepts the transaction into mined blocks at a higher (or lower) " - "priority\n" + RPCHelpMan{"prioritisetransaction", + "Accepts the transaction into mined blocks at a higher " + "(or lower) priority\n", + { + {"txid", RPCArg::Type::STR_HEX, false}, + {"dummy", RPCArg::Type::NUM, false}, + {"fee_delta", RPCArg::Type::NUM, false}, + }} + .ToString() + "\nArguments:\n" "1. \"txid\" (string, required) The transaction id.\n" "2. dummy (numeric, optional) API-Compatibility for " @@ -334,22 +354,45 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() > 1) { throw std::runtime_error( - "getblocktemplate ( \"template_request\" )\n" - "\nIf the request parameters include a 'mode' key, that is used to " - "explicitly select between the default 'template' request or a " - "'proposal'.\n" - "It returns data needed to construct a block to work on.\n" - "For full specification, see BIPs 22, 23, 9, and 145:\n" - " " - "https://github.com/bitcoin/bips/blob/master/bip-0022.mediawiki\n" - " " - "https://github.com/bitcoin/bips/blob/master/bip-0023.mediawiki\n" - " " - "https://github.com/bitcoin/bips/blob/master/" - "bip-0009.mediawiki#getblocktemplate_changes\n" - " " - "https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki\n" - + RPCHelpMan{ + "getblocktemplate", + "\nIf the request parameters include a 'mode' key, that is " + "used to explicitly select between the default 'template' " + "request or a 'proposal'.\n" + "It returns data needed to construct a block to work on.\n" + "For full specification, see BIPs 22, 23, 9, and 145:\n" + " " + "https://github.com/bitcoin/bips/blob/master/" + "bip-0022.mediawiki\n" + " " + "https://github.com/bitcoin/bips/blob/master/" + "bip-0023.mediawiki\n" + " " + "https://github.com/bitcoin/bips/blob/master/" + "bip-0009.mediawiki#getblocktemplate_changes\n" + " ", + { + {"template_request", + RPCArg::Type::OBJ, + { + {"mode", RPCArg::Type::STR, true}, + {"capabilities", + RPCArg::Type::ARR, + { + {"support", RPCArg::Type::STR, true}, + }, + true}, + {"rules", + RPCArg::Type::ARR, + { + {"support", RPCArg::Type::STR, true}, + }, + true}, + }, + true, + "\"template_request\""}, + }} + .ToString() + "\nArguments:\n" "1. template_request (json object, optional) A json object " "in the following spec\n" @@ -697,10 +740,15 @@ if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { throw std::runtime_error( - "submitblock \"hexdata\" ( \"dummy\" )\n" - "\nAttempts to submit new block to network.\n" - "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n" - + RPCHelpMan{"submitblock", + "\nAttempts to submit new block to network.\n" + "See https://en.bitcoin.it/wiki/BIP_0022 for full " + "specification.\n", + { + {"hexdata", RPCArg::Type::STR_HEX, false}, + {"dummy", RPCArg::Type::STR, true}, + }} + .ToString() + "\nArguments\n" "1. \"hexdata\" (string, required) the hex-encoded block " "data to submit\n" @@ -763,18 +811,23 @@ static UniValue submitheader(const Config &config, const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 1) { - throw std::runtime_error("submitheader \"hexdata\"\n" - "\nDecode the given hexdata as a header and " - "submit it as a candidate chain tip if valid." - "\nThrows when the header is invalid.\n" - "\nArguments\n" - "1. \"hexdata\" (string, required) the " - "hex-encoded block header data\n" - "\nResult:\n" - "None" - "\nExamples:\n" + - HelpExampleCli("submitheader", "\"aabbcc\"") + - HelpExampleRpc("submitheader", "\"aabbcc\"")); + throw std::runtime_error( + RPCHelpMan{"submitheader", + "\nDecode the given hexdata as a header and submit it " + "as a candidate chain tip if valid." + "\nThrows when the header is invalid.\n", + { + {"hexdata", RPCArg::Type::STR_HEX, false}, + }} + .ToString() + + "\nArguments\n" + "1. \"hexdata\" (string, required) the " + "hex-encoded block header data\n" + "\nResult:\n" + "None" + "\nExamples:\n" + + HelpExampleCli("submitheader", "\"aabbcc\"") + + HelpExampleRpc("submitheader", "\"aabbcc\"")); } CBlockHeader h; @@ -807,9 +860,11 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() > 0) { throw std::runtime_error( - "estimatefee\n" - "\nEstimates the approximate fee per kilobyte needed for a " - "transaction\n" + RPCHelpMan{"estimatefee", + "\nEstimates the approximate fee per kilobyte needed " + "for a transaction\n", + {}} + .ToString() + "\nResult:\n" "n (numeric) estimated fee-per-kilobyte\n" "\nExample:\n" + diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -33,8 +33,13 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 1) { throw std::runtime_error( - "validateaddress \"address\"\n" - "\nReturn information about the given bitcoin address.\n" + RPCHelpMan{ + "validateaddress", + "\nReturn information about the given bitcoin address.\n", + { + {"address", RPCArg::Type::STR, false}, + }} + .ToString() + "\nArguments:\n" "1. \"address\" (string, required) The bitcoin " "address to validate\n" @@ -162,8 +167,14 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 3) { throw std::runtime_error( - "verifymessage \"address\" \"signature\" \"message\"\n" - "\nVerify a signed message\n" + RPCHelpMan{"verifymessage", + "\nVerify a signed message\n", + { + {"address", RPCArg::Type::STR, false}, + {"signature", RPCArg::Type::STR, false}, + {"message", RPCArg::Type::STR, false}, + }} + .ToString() + "\nArguments:\n" "1. \"address\" (string, required) The bitcoin address to " "use for the signature.\n" @@ -231,8 +242,13 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 2) { throw std::runtime_error( - "signmessagewithprivkey \"privkey\" \"message\"\n" - "\nSign a message with the private key of an address\n" + RPCHelpMan{"signmessagewithprivkey", + "\nSign a message with the private key of an address\n", + { + {"privkey", RPCArg::Type::STR, false}, + {"message", RPCArg::Type::STR, false}, + }} + .ToString() + "\nArguments:\n" "1. \"privkey\" (string, required) The private key to sign " "the message with.\n" @@ -278,8 +294,13 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 1) { throw std::runtime_error( - "setmocktime timestamp\n" - "\nSet the local time to given timestamp (-regtest only)\n" + RPCHelpMan{ + "setmocktime", + "\nSet the local time to given timestamp (-regtest only)\n", + { + {"timestamp", RPCArg::Type::NUM, false}, + }} + .ToString() + "\nArguments:\n" "1. timestamp (integer, required) Unix seconds-since-epoch " "timestamp\n" @@ -341,8 +362,13 @@ */ if (request.fHelp || request.params.size() > 1) { throw std::runtime_error( - "getmemoryinfo (\"mode\")\n" - "Returns an object containing information about memory usage.\n" + RPCHelpMan{"getmemoryinfo", + "Returns an object containing information about memory " + "usage.\n", + { + {"mode", RPCArg::Type::STR, true}, + }} + .ToString() + "Arguments:\n" "1. \"mode\" determines what kind of information is returned. This " "argument is optional, the default mode is \"stats\".\n" @@ -415,23 +441,31 @@ static UniValue logging(const Config &config, const JSONRPCRequest &request) { if (request.fHelp || request.params.size() > 2) { throw std::runtime_error( - "logging ( )\n" - "Gets and sets the logging configuration.\n" - "When called without an argument, returns the list of categories " - "with status that are currently being debug logged or not.\n" - "When called with arguments, adds or removes categories from debug " - "logging and return the lists above.\n" - "The arguments are evaluated in order \"include\", \"exclude\".\n" - "If an item is both included and excluded, it will thus end up " - "being excluded.\n" - "The valid logging categories are: " + - ListLogCategories() + - "\n" - "In addition, the following are available as category names with " - "special meanings:\n" - " - \"all\", \"1\" : represent all logging categories.\n" - " - \"none\", \"0\" : even if other logging categories are " - "specified, ignore all of them.\n" + RPCHelpMan{ + "logging", + "Gets and sets the logging configuration.\n" + "When called without an argument, returns the list of " + "categories with status that are currently being debug logged " + "or not.\n" + "When called with arguments, adds or removes categories from " + "debug logging and return the lists above.\n" + "The arguments are evaluated in order \"include\", " + "\"exclude\".\n" + "If an item is both included and excluded, it will thus end up " + "being excluded.\n" + "The valid logging categories are: " + + ListLogCategories() + + "\n" + "In addition, the following are available as category " + "names with special meanings:\n" + " - \"all\", \"1\" : represent all logging categories.\n" + " - \"none\", \"0\" : even if other logging categories " + "are specified, ignore all of them.\n", + { + {"include", RPCArg::Type::STR, true}, + {"exclude", RPCArg::Type::STR, true}, + }} + .ToString() + "\nArguments:\n" "1. \"include\" (array of strings, optional) A json array " "of categories to add debug logging\n" @@ -501,12 +535,16 @@ static UniValue echo(const Config &config, const JSONRPCRequest &request) { if (request.fHelp) { throw std::runtime_error( - "echo|echojson \"message\" ...\n" - "\nSimply echo back the input arguments. This command is for " - "testing.\n" - "\nThe difference between echo and echojson is that echojson has " - "argument conversion enabled in the client-side table in" - "bitcoin-cli and the GUI. There is no server-side difference."); + RPCHelpMan{ + "echo|echojson ...", + "\nSimply echo back the input arguments. This command is for " + "testing.\n" + "\nThe difference between echo and echojson is that echojson " + "has argument conversion enabled in the client-side table in " + "bitcoin-cli and the GUI. There is no server-side difference.", + {}} + .ToString() + + ""); } return request.params; diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -30,8 +30,10 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 0) { throw std::runtime_error( - "getconnectioncount\n" - "\nReturns the number of connections to other nodes.\n" + RPCHelpMan{"getconnectioncount", + "\nReturns the number of connections to other nodes.\n", + {}} + .ToString() + "\nResult:\n" "n (numeric) The connection count\n" "\nExamples:\n" + @@ -51,15 +53,18 @@ static UniValue ping(const Config &config, const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 0) { throw std::runtime_error( - "ping\n" - "\nRequests that a ping be sent to all other nodes, to measure " - "ping time.\n" - "Results provided in getpeerinfo, pingtime and pingwait fields are " - "decimal seconds.\n" - "Ping command is handled in queue with all other commands, so it " - "measures processing backlog, not just network ping.\n" - "\nExamples:\n" + - HelpExampleCli("ping", "") + HelpExampleRpc("ping", "")); + RPCHelpMan{ + "ping", + "\nRequests that a ping be sent to all other nodes, to measure " + "ping time.\n" + "Results provided in getpeerinfo, pingtime and pingwait fields " + "are decimal seconds.\n" + "Ping command is handled in queue with all other commands, so " + "it measures processing backlog, not just network ping.\n", + {}} + .ToString() + + "\nExamples:\n" + HelpExampleCli("ping", "") + + HelpExampleRpc("ping", "")); } if (!g_connman) { @@ -77,9 +82,11 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 0) { throw std::runtime_error( - "getpeerinfo\n" - "\nReturns data about each connected network node as a json array " - "of objects.\n" + RPCHelpMan{"getpeerinfo", + "\nReturns data about each connected network node as a " + "json array of objects.\n", + {}} + .ToString() + "\nResult:\n" "[\n" " {\n" @@ -248,13 +255,19 @@ (strCommand != "onetry" && strCommand != "add" && strCommand != "remove")) { throw std::runtime_error( - "addnode \"node\" \"command\"\n" - "\nAttempts to add or remove a node from the addnode list.\n" - "Or try a connection to a node once.\n" - "Nodes added using addnode (or -connect) are protected from DoS " - "disconnection and are not required to be\n" - "full nodes as other outbound peers are (though " - "such peers will not be synced from).\n" + RPCHelpMan{ + "addnode", + "\nAttempts to add or remove a node from the addnode list.\n" + "Or try a connection to a node once.\n" + "Nodes added using addnode (or -connect) are protected from " + "DoS disconnection and are not required to be\n" + "full nodes as other outbound peers are (though such peers " + "will not be synced from).\n", + { + {"node", RPCArg::Type::STR, false}, + {"command", RPCArg::Type::STR, false}, + }} + .ToString() + "\nArguments:\n" "1. \"node\" (string, required) The node (see getpeerinfo for " "nodes)\n" @@ -298,12 +311,18 @@ if (request.fHelp || request.params.size() == 0 || request.params.size() >= 3) { throw std::runtime_error( - "disconnectnode ( \"address\" nodeid )\n" - "\nImmediately disconnects from the specified peer node.\n" - "\nStrictly one out of 'address' and 'nodeid' can be provided to " - "identify the node.\n" - "\nTo disconnect by nodeid, either set 'address' to the empty " - "string, or call using the named 'nodeid' argument only.\n" + RPCHelpMan{ + "disconnectnode", + "\nImmediately disconnects from the specified peer node.\n" + "\nStrictly one out of 'address' and 'nodeid' can be provided " + "to identify the node.\n" + "\nTo disconnect by nodeid, either set 'address' to the empty " + "string, or call using the named 'nodeid' argument only.\n", + { + {"address", RPCArg::Type::STR, true}, + {"nodeid", RPCArg::Type::NUM, true}, + }} + .ToString() + "\nArguments:\n" "1. \"address\" (string, optional) The IP address/port of the " "node\n" @@ -353,10 +372,14 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() > 1) { throw std::runtime_error( - "getaddednodeinfo ( \"node\" )\n" - "\nReturns information about the given added node, or all added " - "nodes\n" - "(note that onetry addnodes are not listed here)\n" + RPCHelpMan{"getaddednodeinfo", + "\nReturns information about the given added node, or " + "all added nodes\n" + "(note that onetry addnodes are not listed here)\n", + { + {"node", RPCArg::Type::STR, true}, + }} + .ToString() + "\nArguments:\n" "1. \"node\" (string, optional) If provided, return information " "about this specific node, otherwise all nodes are returned.\n" @@ -430,10 +453,12 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() > 0) { throw std::runtime_error( - "getnettotals\n" - "\nReturns information about network traffic, including bytes in, " - "bytes out,\n" - "and current time.\n" + RPCHelpMan{"getnettotals", + "\nReturns information about network traffic, including " + "bytes in, bytes out,\n" + "and current time.\n", + {}} + .ToString() + "\nResult:\n" "{\n" " \"totalbytesrecv\": n, (numeric) Total bytes received\n" @@ -512,9 +537,11 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 0) { throw std::runtime_error( - "getnetworkinfo\n" - "Returns an object containing various state info regarding P2P " - "networking.\n" + RPCHelpMan{"getnetworkinfo", + "Returns an object containing various state info " + "regarding P2P networking.\n", + {}} + .ToString() + "\nResult:\n" "{\n" " \"version\": xxxxx, (numeric) the server " @@ -623,8 +650,16 @@ if (request.fHelp || request.params.size() < 2 || (strCommand != "add" && strCommand != "remove")) { throw std::runtime_error( - "setban \"subnet\" \"command\" ( bantime absolute )\n" - "\nAttempts to add or remove a IP/Subnet from the banned list.\n" + RPCHelpMan{"setban", + "\nAttempts to add or remove an IP/Subnet from the " + "banned list.\n", + { + {"subnet", RPCArg::Type::STR, false}, + {"command", RPCArg::Type::STR, false}, + {"bantime", RPCArg::Type::NUM, true}, + {"absolute", RPCArg::Type::BOOL, true}, + }} + .ToString() + "\nArguments:\n" "1. \"subnet\" (string, required) The IP/Subnet (see " "getpeerinfo for nodes IP) with an optional netmask (default is " @@ -712,11 +747,11 @@ static UniValue listbanned(const Config &config, const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 0) { - throw std::runtime_error("listbanned\n" - "\nList all banned IPs/Subnets.\n" - "\nExamples:\n" + - HelpExampleCli("listbanned", "") + - HelpExampleRpc("listbanned", "")); + throw std::runtime_error( + RPCHelpMan{"listbanned", "\nList all banned IPs/Subnets.\n", {}} + .ToString() + + "\nExamples:\n" + HelpExampleCli("listbanned", "") + + HelpExampleRpc("listbanned", "")); } if (!g_banman) { @@ -745,13 +780,12 @@ static UniValue clearbanned(const Config &config, const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 0) { - throw std::runtime_error("clearbanned\n" - "\nClear all banned IPs.\n" - "\nExamples:\n" + - HelpExampleCli("clearbanned", "") + - HelpExampleRpc("clearbanned", "")); + throw std::runtime_error( + RPCHelpMan{"clearbanned", "\nClear all banned IPs.\n", {}} + .ToString() + + "\nExamples:\n" + HelpExampleCli("clearbanned", "") + + HelpExampleRpc("clearbanned", "")); } - if (!g_banman) { throw JSONRPCError( RPC_CLIENT_P2P_DISABLED, @@ -767,8 +801,12 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 1) { throw std::runtime_error( - "setnetworkactive state\n" - "\nDisable/enable all p2p network activity.\n" + RPCHelpMan{"setnetworkactive", + "\nDisable/enable all p2p network activity.\n", + { + {"state", RPCArg::Type::BOOL, false}, + }} + .ToString() + "\nArguments:\n" "1. \"state\" (boolean, required) true to " "enable networking, false to disable\n"); @@ -789,9 +827,13 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() > 1) { throw std::runtime_error( - "getnodeaddresses ( count )\n" - "\nReturn known addresses which can potentially be used to find " - "new nodes in the network\n" + RPCHelpMan{"getnodeaddresses", + "\nReturn known addresses which can potentially be used " + "to find new nodes in the network\n", + { + {"count", RPCArg::Type::NUM, true}, + }} + .ToString() + "\nArguments:\n" "1. \"count\" (numeric, optional) How many addresses to return. " "Limited to the smaller of " + diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -67,18 +67,23 @@ if (request.fHelp || request.params.size() < 1 || request.params.size() > 3) { throw std::runtime_error( - "getrawtransaction \"txid\" ( verbose \"blockhash\" )\n" - - "\nNOTE: By default this function only works for mempool " - "transactions. If the -txindex option is\n" - "enabled, it also works for blockchain transactions. If the block " - "which contains the transaction\n" - "is known, its hash can be provided even for nodes without " - "-txindex. Note that if a blockhash is\n" - "provided, only that block will be searched and if the transaction " - "is in the mempool or other\n" - "blocks, or if this node does not have the given block available, " - "the transaction will not be found.\n" + RPCHelpMan{"getrawtransaction", + "\nNOTE: By default this function only works for " + "mempool transactions. If the -txindex option is\n" + "enabled, it also works for blockchain transactions. If " + "the block which contains the transaction\n" + "is known, its hash can be provided even for nodes " + "without -txindex. Note that if a blockhash is\n" + "provided, only that block will be searched and if the " + "transaction is in the mempool or other\n" + "blocks, or if this node does not have the given block " + "available, the transaction will not be found.\n", + { + {"txid", RPCArg::Type::STR_HEX, false}, + {"verbose", RPCArg::Type::BOOL, true}, + {"blockhash", RPCArg::Type::STR_HEX, true}, + }} + .ToString() + "DEPRECATED: for now, it also works for transactions with unspent " "outputs.\n" @@ -243,6 +248,16 @@ (request.params.size() != 1 && request.params.size() != 2)) { throw std::runtime_error( RPCHelpMan{"gettxoutproof", + "\nReturns a hex-encoded proof that \"txid\" was " + "included in a block.\n" + "\nNOTE: By default this function only works sometimes. " + "This is when there is an\n" + "unspent output in the utxo for this transaction. To " + "make it always work,\n" + "you need to maintain a transaction index, using the " + "-txindex command line option or\n" + "specify the block in which the transaction is included " + "manually (by blockhash).\n", { {"txids", RPCArg::Type::ARR, @@ -253,16 +268,6 @@ {"blockhash", RPCArg::Type::STR_HEX, true}, }} .ToString() + - "\nReturns a hex-encoded proof that \"txid\" was included in a " - "block.\n" - "\nNOTE: By default this function only works sometimes. This is " - "when there is an\n" - "unspent output in the utxo for this transaction. To make it " - "always work,\n" - "you need to maintain a transaction index, using the -txindex " - "command line option or\n" - "specify the block in which the transaction is included manually " - "(by blockhash).\n" "\nArguments:\n" "1. \"txids\" (string) A json array of txids to filter\n" " [\n" @@ -369,10 +374,15 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 1) { throw std::runtime_error( - "verifytxoutproof \"proof\"\n" - "\nVerifies that a proof points to a transaction in a block, " - "returning the transaction it commits to\n" - "and throwing an RPC error if the block is not in our best chain\n" + RPCHelpMan{"verifytxoutproof", + "\nVerifies that a proof points to a transaction in a " + "block, returning the transaction it commits to\n" + "and throwing an RPC error if the block is not in our " + "best chain\n", + { + {"proof", RPCArg::Type::STR_HEX, false}, + }} + .ToString() + "\nArguments:\n" "1. \"proof\" (string, required) The hex-encoded proof " "generated by gettxoutproof\n" @@ -602,10 +612,13 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 1) { throw std::runtime_error( - "decoderawtransaction \"hexstring\"\n" - "\nReturn a JSON object representing the serialized, hex-encoded " - "transaction.\n" - + RPCHelpMan{"decoderawtransaction", + "\nReturn a JSON object representing the serialized, " + "hex-encoded transaction.\n", + { + {"hexstring", RPCArg::Type::STR_HEX, false}, + }} + .ToString() + "\nArguments:\n" "1. \"hexstring\" (string, required) The transaction hex " "string\n" @@ -676,8 +689,12 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 1) { throw std::runtime_error( - "decodescript \"hexstring\"\n" - "\nDecode a hex-encoded script.\n" + RPCHelpMan{"decodescript", + "\nDecode a hex-encoded script.\n", + { + {"hexstring", RPCArg::Type::STR_HEX, false}, + }} + .ToString() + "\nArguments:\n" "1. \"hexstring\" (string) the hex-encoded script\n" "\nResult:\n" @@ -745,6 +762,11 @@ if (request.fHelp || request.params.size() != 1) { throw std::runtime_error( RPCHelpMan{"combinerawtransaction", + "\nCombine multiple partially signed transactions into " + "one transaction.\n" + "The combined transaction may be another partially " + "signed transaction or a \n" + "fully signed transaction.", { {"txs", RPCArg::Type::ARR, @@ -754,11 +776,6 @@ false}, }} .ToString() + - "\nCombine multiple partially signed transactions into one " - "transaction.\n" - "The combined transaction may be another partially signed " - "transaction or a \n" - "fully signed transaction." "\nArguments:\n" "1. \"txs\" (string) A json array of hex strings of " @@ -1026,6 +1043,14 @@ throw std::runtime_error( RPCHelpMan{ "signrawtransactionwithkey", + "\nSign inputs for raw transaction (serialized, hex-encoded).\n" + "The second argument is an array of base58-encoded private\n" + "keys that will be the only keys used to sign the " + "transaction.\n" + "The third optional argument (may be null) is an array of " + "previous transaction outputs that\n" + "this transaction depends on but may not yet be in the block " + "chain.\n", { {"hexstring", RPCArg::Type::STR_HEX, false}, {"privkyes", @@ -1052,13 +1077,6 @@ {"sighashtype", RPCArg::Type::STR, true}, }} .ToString() + - "\nSign inputs for raw transaction (serialized, hex-encoded).\n" - "The second argument is an array of base58-encoded private\n" - "keys that will be the only keys used to sign the transaction.\n" - "The third optional argument (may be null) is an array of previous " - "transaction outputs that\n" - "this transaction depends on but may not yet be in the block " - "chain.\n" "\nArguments:\n" "1. \"hexstring\" (string, required) The " @@ -1156,11 +1174,16 @@ if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { throw std::runtime_error( - "sendrawtransaction \"hexstring\" ( allowhighfees )\n" - "\nSubmits raw transaction (serialized, hex-encoded) to local node " - "and network.\n" - "\nAlso see createrawtransaction and signrawtransactionwithkey " - "calls.\n" + RPCHelpMan{"sendrawtransaction", + "\nSubmits raw transaction (serialized, hex-encoded) to " + "local node and network.\n" + "\nAlso see createrawtransaction and " + "signrawtransactionwithkey calls.\n", + { + {"hexstring", RPCArg::Type::STR_HEX, false}, + {"allowhighfees", RPCArg::Type::BOOL, true}, + }} + .ToString() + "\nArguments:\n" "1. \"hexstring\" (string, required) The hex string of the raw " "transaction)\n" @@ -1369,10 +1392,13 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 1) { throw std::runtime_error( - "decodepsbt \"psbt\"\n" - "\nReturn a JSON object representing the serialized, " - "base64-encoded partially signed Bitcoin transaction.\n" - + RPCHelpMan{"decodepsbt", + "\nReturn a JSON object representing the serialized, " + "base64-encoded partially signed Bitcoin transaction.\n", + { + {"psbt", RPCArg::Type::STR, false}, + }} + .ToString() + "\nArguments:\n" "1. \"psbt\" (string, required) The PSBT base64 string\n" @@ -1647,18 +1673,18 @@ if (request.fHelp || request.params.size() != 1) { throw std::runtime_error( RPCHelpMan{"combinepsbt", + "\nCombine multiple partially signed Bitcoin " + "transactions into one transaction.\n" + "Implements the Combiner role.\n", { {"txs", RPCArg::Type::ARR, { - {"psbt", RPCArg::Type::STR_HEX, false}, + {"psbt", RPCArg::Type::STR, false}, }, false}, }} .ToString() + - "\nCombine multiple partially signed Bitcoin transactions into one " - "transaction.\n" - "Implements the Combiner role.\n" "\nArguments:\n" "1. \"txs\" (string) A json array of base64 " "strings of partially signed transactions\n" @@ -1717,14 +1743,19 @@ if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { throw std::runtime_error( - "finalizepsbt \"psbt\" ( extract )\n" - "Finalize the inputs of a PSBT. If the transaction is fully " - "signed, it will produce a\n" - "network serialized transaction which can be broadcast with " - "sendrawtransaction. Otherwise a PSBT will be\n" - "created which has the final_scriptSigfields filled for inputs " - "that are complete.\n" - "Implements the Finalizer and Extractor roles.\n" + RPCHelpMan{"finalizepsbt", + "Finalize the inputs of a PSBT. If the transaction is " + "fully signed, it will produce a\n" + "network serialized transaction which can be broadcast " + "with sendrawtransaction. Otherwise a PSBT will be\n" + "created which has the final_scriptSigfields filled for " + "inputs that are complete.\n" + "Implements the Finalizer and Extractor roles.\n", + { + {"psbt", RPCArg::Type::STR, false}, + {"extract", RPCArg::Type::BOOL, true}, + }} + .ToString() + "\nArguments:\n" "1. \"psbt\" (string) A base64 string of a PSBT\n" "2. \"extract\" (boolean, optional, default=true) If " @@ -1793,6 +1824,9 @@ request.params.size() > 3) { throw std::runtime_error( RPCHelpMan{"createpsbt", + "\nCreates a transaction in the Partially Signed " + "Transaction format.\n" + "Implements the Creator role.\n", { {"inputs", RPCArg::Type::ARR, @@ -1827,9 +1861,6 @@ {"locktime", RPCArg::Type::NUM, true}, }} .ToString() + - "\nCreates a transaction in the Partially Signed Transaction " - "format.\n" - "Implements the Creator role.\n" "\nArguments:\n" "1. \"inputs\" (array, required) A json array of " "json objects\n" @@ -1908,12 +1939,17 @@ if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { throw std::runtime_error( - "converttopsbt \"hexstring\" ( permitsigdata )\n" - "\nConverts a network serialized transaction to a PSBT. This " - "should be used only with createrawtransaction and " - "fundrawtransaction\n" - "createpsbt and walletcreatefundedpsbt should be used for new " - "applications.\n" + RPCHelpMan{"converttopsbt", + "\nConverts a network serialized transaction to a PSBT. " + "This should be used only with createrawtransaction and " + "fundrawtransaction\n" + "createpsbt and walletcreatefundedpsbt should be used " + "for new applications.\n", + { + {"hexstring", RPCArg::Type::STR_HEX, false}, + {"permitsigdata", RPCArg::Type::BOOL, true}, + }} + .ToString() + "\nArguments:\n" "1. \"hexstring\" (string, required) The hex string " "of a raw transaction\n" diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -287,8 +287,13 @@ static UniValue help(Config &config, const JSONRPCRequest &jsonRequest) { if (jsonRequest.fHelp || jsonRequest.params.size() > 1) { throw std::runtime_error( - "help ( \"command\" )\n" - "\nList all commands, or get help for a specified command.\n" + RPCHelpMan{ + "help", + "\nList all commands, or get help for a specified command.\n", + { + {"command", RPCArg::Type::STR, true}, + }} + .ToString() + "\nArguments:\n" "1. \"command\" (string, optional) The command to get help on\n" "\nResult:\n" @@ -309,8 +314,8 @@ // 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("stop\n" - "\nStop Bitcoin server."); + throw std::runtime_error( + RPCHelpMan{"stop", "\nStop Bitcoin server.", {}}.ToString()); } // Event loop will exit after current HTTP requests have been handled, so @@ -325,14 +330,15 @@ static UniValue uptime(const Config &config, const JSONRPCRequest &jsonRequest) { if (jsonRequest.fHelp || jsonRequest.params.size() > 0) { - throw std::runtime_error("uptime\n" - "\nReturns the total uptime of the server.\n" - "\nResult:\n" - "ttt (numeric) The number of seconds " - "that the server has been running\n" - "\nExamples:\n" + - HelpExampleCli("uptime", "") + - HelpExampleRpc("uptime", "")); + throw std::runtime_error( + RPCHelpMan{ + "uptime", "\nReturns the total uptime of the server.\n", {}} + .ToString() + + "\nResult:\n" + "ttt (numeric) The number of seconds " + "that the server has been running\n" + "\nExamples:\n" + + HelpExampleCli("uptime", "") + HelpExampleRpc("uptime", "")); } return GetTime() - GetStartupTime(); @@ -341,8 +347,10 @@ static UniValue getrpcinfo(const Config &config, const JSONRPCRequest &request) { if (request.fHelp || request.params.size() > 0) { - throw std::runtime_error("getrpcinfo\n" - "\nReturns details of the RPC server.\n"); + throw std::runtime_error(RPCHelpMan{ + "getrpcinfo", + "\nReturns details of the RPC server.\n", + {}}.ToString()); } LOCK(g_rpc_server_info.mutex); diff --git a/src/rpc/util.h b/src/rpc/util.h --- a/src/rpc/util.h +++ b/src/rpc/util.h @@ -53,15 +53,22 @@ //! Only used for arrays or dicts const std::vector m_inner; const bool m_optional; - - RPCArg(const std::string &name, const Type &type, const bool optional) - : m_name{name}, m_type{type}, m_optional{optional} { + //! Should be empty unless it is supposed to override the auto-generated + //! summary line + const std::string m_oneline_description; + + RPCArg(const std::string &name, const Type &type, const bool optional, + const std::string &oneline_description = "") + : m_name{name}, m_type{type}, m_optional{optional}, + m_oneline_description{oneline_description} { assert(type != Type::ARR && type != Type::OBJ); } RPCArg(const std::string &name, const Type &type, - const std::vector &inner, const bool optional) - : m_name{name}, m_type{type}, m_inner{inner}, m_optional{optional} { + const std::vector &inner, const bool optional, + const std::string &oneline_description = "") + : m_name{name}, m_type{type}, m_inner{inner}, m_optional{optional}, + m_oneline_description{oneline_description} { assert(type == Type::ARR || type == Type::OBJ); } @@ -73,13 +80,15 @@ class RPCHelpMan { public: - RPCHelpMan(const std::string &name, const std::vector &args) - : m_name{name}, m_args{args} {} + RPCHelpMan(const std::string &name, const std::string &description, + const std::vector &args) + : m_name{name}, m_description{description}, m_args{args} {} std::string ToString() const; private: const std::string m_name; + const std::string m_description; const std::vector m_args; }; diff --git a/src/rpc/util.cpp b/src/rpc/util.cpp --- a/src/rpc/util.cpp +++ b/src/rpc/util.cpp @@ -141,6 +141,8 @@ } ret += "\n"; + ret += m_description; + return ret; } @@ -174,6 +176,10 @@ } std::string RPCArg::ToString() const { + if (!m_oneline_description.empty()) { + return m_oneline_description; + } + switch (m_type) { case Type::STR_HEX: case Type::STR: { diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -101,9 +101,15 @@ if (request.fHelp || request.params.size() < 1 || request.params.size() > 3) { throw std::runtime_error( - "importprivkey \"privkey\" ( \"label\" ) ( rescan )\n" - "\nAdds a private key (as returned by dumpprivkey) to your wallet. " - "Requires a new wallet backup.\n" + RPCHelpMan{"importprivkey", + "\nAdds a private key (as returned by dumpprivkey) to " + "your wallet. Requires a new wallet backup.\n", + { + {"privkey", RPCArg::Type::STR, false}, + {"label", RPCArg::Type::STR, true}, + {"rescan", RPCArg::Type::BOOL, true}, + }} + .ToString() + "Hint: use importmulti to import more than one private key.\n" "\nArguments:\n" "1. \"privkey\" (string, required) The private key (see " @@ -215,16 +221,18 @@ } if (request.fHelp || request.params.size() > 0) { - throw std::runtime_error("abortrescan\n" - "\nStops current wallet rescan triggered by " - "an RPC call, e.g. by an importprivkey call.\n" - "\nExamples:\n" - "\nImport a private key\n" + - HelpExampleCli("importprivkey", "\"mykey\"") + - "\nAbort the running wallet rescan\n" + - HelpExampleCli("abortrescan", "") + - "\nAs a JSON-RPC call\n" + - HelpExampleRpc("abortrescan", "")); + throw std::runtime_error( + RPCHelpMan{"abortrescan", + "\nStops current wallet rescan triggered by " + "an RPC call, e.g. by an importprivkey call.\n", + {}} + .ToString() + + "\nExamples:\n" + "\nImport a private key\n" + + HelpExampleCli("importprivkey", "\"mykey\"") + + "\nAbort the running wallet rescan\n" + + HelpExampleCli("abortrescan", "") + "\nAs a JSON-RPC call\n" + + HelpExampleRpc("abortrescan", "")); } if (!pwallet->IsScanning() || pwallet->IsAbortingRescan()) { @@ -288,10 +296,17 @@ if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) { throw std::runtime_error( - "importaddress \"address\" ( \"label\" rescan p2sh )\n" - "\nAdds an address or script (in hex) that can be watched as if it " - "were in your wallet but cannot be used to spend. Requires a new " - "wallet backup.\n" + RPCHelpMan{"importaddress", + "\nAdds an address or script (in hex) that can be " + "watched as if it were in your wallet but cannot be " + "used to spend. Requires a new wallet backup.\n", + { + {"address", RPCArg::Type::STR, false}, + {"label", RPCArg::Type::STR, true}, + {"rescan", RPCArg::Type::BOOL, true}, + {"p2sh", RPCArg::Type::BOOL, true}, + }} + .ToString() + "\nArguments:\n" "1. \"address\" (string, required) The Bitcoin address " "(or hex-encoded script)\n" @@ -391,13 +406,18 @@ if (request.fHelp || request.params.size() != 2) { throw std::runtime_error( - "importprunedfunds \"rawtransaction\" \"txoutproof\"\n" - "\nImports funds without rescan. Corresponding address or script " - "must previously be included in wallet. Aimed towards pruned " - "wallets. The end-user is responsible to import additional " - "transactions that subsequently spend the imported outputs or " - "rescan after the point in the blockchain the transaction is " - "included.\n" + RPCHelpMan{"importprunedfunds", + "\nImports funds without rescan. Corresponding address " + "or script must previously be included in wallet. Aimed " + "towards pruned wallets. The end-user is responsible to " + "import additional transactions that subsequently spend " + "the imported outputs or rescan after the point in the " + "blockchain the transaction is included.\n", + { + {"rawtransaction", RPCArg::Type::STR_HEX, false}, + {"txoutproof", RPCArg::Type::STR_HEX, false}, + }} + .ToString() + "\nArguments:\n" "1. \"rawtransaction\" (string, required) A raw transaction in hex " "funding an already-existing address in wallet\n" @@ -471,10 +491,15 @@ if (request.fHelp || request.params.size() != 1) { throw std::runtime_error( - "removeprunedfunds \"txid\"\n" - "\nDeletes the specified transaction from the wallet. Meant for " - "use with pruned wallets and as a companion to importprunedfunds. " - "This will affect wallet balances.\n" + RPCHelpMan{ + "removeprunedfunds", + "\nDeletes the specified transaction from the wallet. Meant " + "for use with pruned wallets and as a companion to " + "importprunedfunds. This will affect wallet balances.\n", + { + {"txid", RPCArg::Type::STR_HEX, false}, + }} + .ToString() + "\nArguments:\n" "1. \"txid\" (string, required) The hex-encoded id of " "the transaction you are deleting\n" @@ -519,10 +544,16 @@ if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) { throw std::runtime_error( - "importpubkey \"pubkey\" ( \"label\" rescan )\n" - "\nAdds a public key (in hex) that can be watched as if it were in " - "your wallet but cannot be used to spend. Requires a new wallet " - "backup.\n" + RPCHelpMan{"importpubkey", + "\nAdds a public key (in hex) that can be watched as if " + "it were in your wallet but cannot be used to spend. " + "Requires a new wallet backup.\n", + { + {"pubkey", RPCArg::Type::STR, false}, + {"label", RPCArg::Type::STR, true}, + {"rescan", RPCArg::Type::BOOL, true}, + }} + .ToString() + "\nArguments:\n" "1. \"pubkey\" (string, required) The hex-encoded public " "key\n" @@ -606,9 +637,14 @@ if (request.fHelp || request.params.size() != 1) { throw std::runtime_error( - "importwallet \"filename\"\n" - "\nImports keys from a wallet dump file (see dumpwallet). Requires " - "a new wallet backup to include imported keys.\n" + RPCHelpMan{ + "importwallet", + "\nImports keys from a wallet dump file (see dumpwallet). " + "Requires a new wallet backup to include imported keys.\n", + { + {"filename", RPCArg::Type::STR, false}, + }} + .ToString() + "\nArguments:\n" "1. \"filename\" (string, required) The wallet file\n" "\nExamples:\n" @@ -804,9 +840,13 @@ if (request.fHelp || request.params.size() != 1) { throw std::runtime_error( - "dumpprivkey \"address\"\n" - "\nReveals the private key corresponding to 'address'.\n" - "Then the importprivkey can be used with this output\n" + RPCHelpMan{"dumpprivkey", + "\nReveals the private key corresponding to 'address'.\n" + "Then the importprivkey can be used with this output\n", + { + {"address", RPCArg::Type::STR, false}, + }} + .ToString() + "\nArguments:\n" "1. \"address\" (string, required) The bitcoin address for the " "private key\n" @@ -851,16 +891,22 @@ if (request.fHelp || request.params.size() != 1) { throw std::runtime_error( - "dumpwallet \"filename\"\n" - "\nDumps all wallet keys in a human-readable format to a " - "server-side file. This does not allow overwriting existing " - "files.\n" - "Imported scripts are included in the dumpsfile, but corresponding " - "addresses may not be added automatically by importwallet.\n" - "Note that if your wallet contains keys which are not derived from " - "your HD seed (e.g. imported keys), these are not covered by\n" - "only backing up the seed itself, and must be backed up too (e.g. " - "ensure you back up the whole dumpfile).\n" + RPCHelpMan{"dumpwallet", + "\nDumps all wallet keys in a human-readable format to " + "a server-side file. This does not allow overwriting " + "existing files.\n" + "Imported scripts are included in the dumpsfile, but " + "corresponding addresses may not be added automatically " + "by importwallet.\n" + "Note that if your wallet contains keys which are not " + "derived from your HD seed (e.g. imported keys), these " + "are not covered by\n" + "only backing up the seed itself, and must be backed up " + "too (e.g. ensure you back up the whole dumpfile).\n", + { + {"filename", RPCArg::Type::STR, false}, + }} + .ToString() + "\nArguments:\n" "1. \"filename\" (string, required) The filename with path " "(either absolute or relative to bitcoind)\n" @@ -1389,48 +1435,131 @@ return NullUniValue; } - // clang-format off - if (mainRequest.fHelp || mainRequest.params.size() < 1 || mainRequest.params.size() > 2) { + if (mainRequest.fHelp || mainRequest.params.size() < 1 || + mainRequest.params.size() > 2) { throw std::runtime_error( - "importmulti \"requests\" ( \"options\" )\n" - "\nImport addresses/scripts (with private or public keys, redeem script (P2SH)), rescanning all addresses in one-shot-only (rescan can be disabled via options). Requires a new wallet backup.\n\n" + RPCHelpMan{ + "importmulti", + "\nImport addresses/scripts (with private or public keys, " + "redeem script (P2SH)), rescanning all addresses in " + "one-shot-only (rescan can be disabled via options). Requires " + "a new wallet backup.\n\n", + { + {"requests", + RPCArg::Type::ARR, + { + {"", + RPCArg::Type::OBJ, + { + { + {"scriptPubKey", RPCArg::Type::STR, false}, + {"timestamp", RPCArg::Type::NUM, false}, + {"redeemscript", RPCArg::Type::STR, true}, + {"pubkeys", + RPCArg::Type::ARR, + { + {"pubkey", RPCArg::Type::STR, false}, + }, + true}, + {"keys", + RPCArg::Type::ARR, + { + {"key", RPCArg::Type::STR, false}, + }, + true}, + {"internal", RPCArg::Type::BOOL, true}, + {"watchonly", RPCArg::Type::BOOL, true}, + {"label", RPCArg::Type::STR, true}, + }, + }, + false}, + }, + false, + "\"requests\""}, + {"options", + RPCArg::Type::OBJ, + { + {"rescan", RPCArg::Type::BOOL, true}, + }, + true, + "\"options\""}, + }} + .ToString() + "Arguments:\n" "1. requests (array, required) Data to be imported\n" " [ (array of json objects)\n" " {\n" - " \"scriptPubKey\": \"