diff --git a/src/rest.cpp b/src/rest.cpp index 25308263e3cf..0c83b3cef152 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -334,7 +334,7 @@ static bool rest_block_notxdetails(const CoreContext& context, HTTPRequest* req, } // A bit of a hack - dependency on a function defined in rpc/blockchain.cpp -UniValue getblockchaininfo(const JSONRPCRequest& request); +RPCHelpMan getblockchaininfo(); static bool rest_chaininfo(const CoreContext& context, HTTPRequest* req, const std::string& strURIPart) { @@ -347,7 +347,7 @@ static bool rest_chaininfo(const CoreContext& context, HTTPRequest* req, const s case RetFormat::JSON: { JSONRPCRequest jsonRequest(context); jsonRequest.params = UniValue(UniValue::VARR); - UniValue chainInfoObject = getblockchaininfo(jsonRequest); + UniValue chainInfoObject = getblockchaininfo().HandleRequest(jsonRequest); std::string strJSON = chainInfoObject.write() + "\n"; req->WriteHeader("Content-Type", "application/json"); req->WriteReply(HTTP_OK, strJSON); diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 68b245daff0b..e4a37197bff7 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -242,9 +242,9 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* tip, const CBlockIn return result; } -static UniValue getblockcount(const JSONRPCRequest& request) +static RPCHelpMan getblockcount() { - RPCHelpMan{"getblockcount", + return RPCHelpMan{"getblockcount", "\nReturns the height of the most-work fully-validated chain.\n" "The genesis block has height 0.\n", {}, @@ -254,16 +254,18 @@ static UniValue getblockcount(const JSONRPCRequest& request) HelpExampleCli("getblockcount", "") + HelpExampleRpc("getblockcount", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ ChainstateManager& chainman = EnsureAnyChainman(request.context); LOCK(cs_main); return chainman.ActiveChain().Height(); +}, + }; } -static UniValue getbestblockhash(const JSONRPCRequest& request) +static RPCHelpMan getbestblockhash() { - RPCHelpMan{"getbestblockhash", + return RPCHelpMan{"getbestblockhash", "\nReturns the hash of the best (tip) block in the most-work fully-validated chain.\n", {}, RPCResult{ @@ -272,16 +274,18 @@ static UniValue getbestblockhash(const JSONRPCRequest& request) HelpExampleCli("getbestblockhash", "") + HelpExampleRpc("getbestblockhash", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ ChainstateManager& chainman = EnsureAnyChainman(request.context); LOCK(cs_main); return chainman.ActiveChain().Tip()->GetBlockHash().GetHex(); +}, + }; } -static UniValue getbestchainlock(const JSONRPCRequest& request) +static RPCHelpMan getbestchainlock() { - RPCHelpMan{"getbestchainlock", + return RPCHelpMan{"getbestchainlock", "\nReturns information about the best ChainLock. Throws an error if there is no known ChainLock yet.", {}, RPCResult{ @@ -296,7 +300,8 @@ static UniValue getbestchainlock(const JSONRPCRequest& request) HelpExampleCli("getbestchainlock", "") + HelpExampleRpc("getbestchainlock", "") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ UniValue result(UniValue::VOBJ); const NodeContext& node = EnsureAnyNodeContext(request.context); @@ -314,6 +319,8 @@ static UniValue getbestchainlock(const JSONRPCRequest& request) LOCK(cs_main); result.pushKV("known_block", chainman.m_blockman.LookupBlockIndex(clsig.getBlockHash()) != nullptr); return result; +}, + }; } void RPCNotifyBlockChange(const CBlockIndex* pindex) @@ -326,9 +333,9 @@ void RPCNotifyBlockChange(const CBlockIndex* pindex) cond_blockchange.notify_all(); } -static UniValue waitfornewblock(const JSONRPCRequest& request) +static RPCHelpMan waitfornewblock() { - RPCHelpMan{"waitfornewblock", + return RPCHelpMan{"waitfornewblock", "\nWaits for a specific new block and returns useful info about it.\n" "\nReturns the current block on timeout or exit.\n", { @@ -344,7 +351,8 @@ static UniValue waitfornewblock(const JSONRPCRequest& request) HelpExampleCli("waitfornewblock", "1000") + HelpExampleRpc("waitfornewblock", "1000") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ int timeout = 0; if (!request.params[0].isNull()) timeout = request.params[0].get_int(); @@ -363,11 +371,13 @@ static UniValue waitfornewblock(const JSONRPCRequest& request) ret.pushKV("hash", block.hash.GetHex()); ret.pushKV("height", block.height); return ret; +}, + }; } -static UniValue waitforblock(const JSONRPCRequest& request) +static RPCHelpMan waitforblock() { - RPCHelpMan{"waitforblock", + return RPCHelpMan{"waitforblock", "\nWaits for a specific new block and returns useful info about it.\n" "\nReturns the current block on timeout or exit.\n", { @@ -384,7 +394,8 @@ static UniValue waitforblock(const JSONRPCRequest& request) HelpExampleCli("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\" 1000") + HelpExampleRpc("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ int timeout = 0; uint256 hash(ParseHashV(request.params[0], "blockhash")); @@ -406,11 +417,13 @@ static UniValue waitforblock(const JSONRPCRequest& request) ret.pushKV("hash", block.hash.GetHex()); ret.pushKV("height", block.height); return ret; +}, + }; } -static UniValue waitforblockheight(const JSONRPCRequest& request) +static RPCHelpMan waitforblockheight() { - RPCHelpMan{"waitforblockheight", + return RPCHelpMan{"waitforblockheight", "\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", @@ -428,7 +441,8 @@ static UniValue waitforblockheight(const JSONRPCRequest& request) HelpExampleCli("waitforblockheight", "100 1000") + HelpExampleRpc("waitforblockheight", "100, 1000") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ int timeout = 0; int height = request.params[0].get_int(); @@ -449,11 +463,13 @@ static UniValue waitforblockheight(const JSONRPCRequest& request) ret.pushKV("hash", block.hash.GetHex()); ret.pushKV("height", block.height); return ret; +}, + }; } -static UniValue syncwithvalidationinterfacequeue(const JSONRPCRequest& request) +static RPCHelpMan syncwithvalidationinterfacequeue() { - RPCHelpMan{"syncwithvalidationinterfacequeue", + return RPCHelpMan{"syncwithvalidationinterfacequeue", "\nWaits for the validation interface queue to catch up on everything that was there when we entered this function.\n", {}, RPCResult{RPCResult::Type::NONE, "", ""}, @@ -461,14 +477,17 @@ static UniValue syncwithvalidationinterfacequeue(const JSONRPCRequest& request) HelpExampleCli("syncwithvalidationinterfacequeue","") + HelpExampleRpc("syncwithvalidationinterfacequeue","") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ SyncWithValidationInterfaceQueue(); return NullUniValue; +}, + }; } -static UniValue getdifficulty(const JSONRPCRequest& request) +static RPCHelpMan getdifficulty() { - RPCHelpMan{"getdifficulty", + return RPCHelpMan{"getdifficulty", "\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n", {}, RPCResult{ @@ -477,11 +496,14 @@ static UniValue getdifficulty(const JSONRPCRequest& request) HelpExampleCli("getdifficulty", "") + HelpExampleRpc("getdifficulty", "") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ ChainstateManager& chainman = EnsureAnyChainman(request.context); LOCK(cs_main); return GetDifficulty(chainman.ActiveChain().Tip()); +}, + }; } static std::vector MempoolEntryDescription() { return { @@ -588,9 +610,9 @@ UniValue MempoolToJSON(const CTxMemPool& pool, llmq::CInstantSendManager* isman, } } -static UniValue getrawmempool(const JSONRPCRequest& request) +static RPCHelpMan getrawmempool() { - RPCHelpMan{"getrawmempool", + return RPCHelpMan{"getrawmempool", "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n" "\nHint: use getmempoolentry to fetch a specific transaction from the mempool.\n", { @@ -612,8 +634,8 @@ static UniValue getrawmempool(const JSONRPCRequest& request) HelpExampleCli("getrawmempool", "true") + HelpExampleRpc("getrawmempool", "true") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ bool fVerbose = false; if (!request.params[0].isNull()) fVerbose = request.params[0].get_bool(); @@ -622,11 +644,13 @@ static UniValue getrawmempool(const JSONRPCRequest& request) const CTxMemPool& mempool = EnsureMemPool(node); LLMQContext& llmq_ctx = EnsureLLMQContext(node); return MempoolToJSON(mempool, llmq_ctx.isman, fVerbose); +}, + }; } -static UniValue getmempoolancestors(const JSONRPCRequest& request) +static RPCHelpMan getmempoolancestors() { - RPCHelpMan{"getmempoolancestors", + return RPCHelpMan{"getmempoolancestors", "\nIf txid is in the mempool, returns all in-mempool ancestors.\n", { {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id (must be in mempool)"}, @@ -646,8 +670,8 @@ static UniValue getmempoolancestors(const JSONRPCRequest& request) HelpExampleCli("getmempoolancestors", "\"mytxid\"") + HelpExampleRpc("getmempoolancestors", "\"mytxid\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ bool fVerbose = false; if (!request.params[1].isNull()) fVerbose = request.params[1].get_bool(); @@ -687,11 +711,13 @@ static UniValue getmempoolancestors(const JSONRPCRequest& request) } return o; } +}, + }; } -static UniValue getmempooldescendants(const JSONRPCRequest& request) +static RPCHelpMan getmempooldescendants() { - RPCHelpMan{"getmempooldescendants", + return RPCHelpMan{"getmempooldescendants", "\nIf txid is in the mempool, returns all in-mempool descendants.\n", { {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id (must be in mempool)"}, @@ -711,8 +737,8 @@ static UniValue getmempooldescendants(const JSONRPCRequest& request) HelpExampleCli("getmempooldescendants", "\"mytxid\"") + HelpExampleRpc("getmempooldescendants", "\"mytxid\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ bool fVerbose = false; if (!request.params[1].isNull()) fVerbose = request.params[1].get_bool(); @@ -753,11 +779,13 @@ static UniValue getmempooldescendants(const JSONRPCRequest& request) } return o; } +}, + }; } -static UniValue getmempoolentry(const JSONRPCRequest& request) +static RPCHelpMan getmempoolentry() { - RPCHelpMan{"getmempoolentry", + return RPCHelpMan{"getmempoolentry", "\nReturns mempool data for given transaction\n", { {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id (must be in mempool)"}, @@ -768,7 +796,8 @@ static UniValue getmempoolentry(const JSONRPCRequest& request) HelpExampleCli("getmempoolentry", "\"mytxid\"") + HelpExampleRpc("getmempoolentry", "\"mytxid\"") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ uint256 hash(ParseHashV(request.params[0], "parameter 1")); @@ -787,11 +816,13 @@ static UniValue getmempoolentry(const JSONRPCRequest& request) LLMQContext& llmq_ctx = EnsureLLMQContext(node); entryToJSON(mempool, info, e, llmq_ctx.isman); return info; +}, + }; } -static UniValue getblockhashes(const JSONRPCRequest& request) +static RPCHelpMan getblockhashes() { - RPCHelpMan{"getblockhashes", + return RPCHelpMan{"getblockhashes", "\nReturns array of hashes of blocks within the timestamp range provided.\n", { {"high", RPCArg::Type::NUM, RPCArg::Optional::NO, "The newer block timestamp"}, @@ -804,8 +835,8 @@ static UniValue getblockhashes(const JSONRPCRequest& request) HelpExampleCli("getblockhashes", "1231614698 1231024505") + HelpExampleRpc("getblockhashes", "1231614698, 1231024505") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ unsigned int high = request.params[0].get_int(); unsigned int low = request.params[1].get_int(); std::vector blockHashes; @@ -820,11 +851,13 @@ static UniValue getblockhashes(const JSONRPCRequest& request) } return result; +}, + }; } -static UniValue getblockhash(const JSONRPCRequest& request) +static RPCHelpMan getblockhash() { - RPCHelpMan{"getblockhash", + return RPCHelpMan{"getblockhash", "\nReturns hash of block in best-block-chain at height provided.\n", { {"height", RPCArg::Type::NUM, RPCArg::Optional::NO, "The height index"}, @@ -835,8 +868,8 @@ static UniValue getblockhash(const JSONRPCRequest& request) HelpExampleCli("getblockhash", "1000") + HelpExampleRpc("getblockhash", "1000") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ ChainstateManager& chainman = EnsureAnyChainman(request.context); LOCK(cs_main); const CChain& active_chain = chainman.ActiveChain(); @@ -847,11 +880,13 @@ static UniValue getblockhash(const JSONRPCRequest& request) CBlockIndex* pblockindex = active_chain[nHeight]; return pblockindex->GetBlockHash().GetHex(); +}, + }; } -static UniValue getblockheader(const JSONRPCRequest& request) +static RPCHelpMan getblockheader() { - RPCHelpMan{"getblockheader", + return 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", { @@ -886,8 +921,8 @@ static UniValue getblockheader(const JSONRPCRequest& request) HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") + HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ uint256 hash(ParseHashV(request.params[0], "hash")); const NodeContext& node = EnsureAnyNodeContext(request.context); @@ -918,16 +953,18 @@ static UniValue getblockheader(const JSONRPCRequest& request) LLMQContext& llmq_ctx = EnsureLLMQContext(node); return blockheaderToJSON(tip, pblockindex, *llmq_ctx.clhandler, *llmq_ctx.isman); +}, + }; } -static UniValue getblockheaders(const JSONRPCRequest& request) +static RPCHelpMan getblockheaders() { - RPCHelpMan{"getblockheaders", + return RPCHelpMan{"getblockheaders", "\nReturns an array of items with information about blockheaders starting from .\n" "\nIf verbose is false, each item is a string that is serialized, hex-encoded data for a single blockheader.\n" "If verbose is true, each item is an Object with information about a single blockheader.\n", { - {"hash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The block hash"}, + {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The block hash"}, {"count", RPCArg::Type::NUM, /* default */ strprintf("%s", MAX_HEADERS_RESULTS), ""}, {"verbose", RPCArg::Type::BOOL, /* default */ "true", "true for a json object, false for the hex-encoded data"}, }, @@ -962,7 +999,8 @@ static UniValue getblockheaders(const JSONRPCRequest& request) HelpExampleCli("getblockheaders", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\" 2000") + HelpExampleRpc("getblockheaders", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\" 2000") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ uint256 hash(ParseHashV(request.params[0], "blockhash")); @@ -1021,6 +1059,8 @@ static UniValue getblockheaders(const JSONRPCRequest& request) } return arrHeaders; +}, + }; } static CBlock GetBlockChecked(const CBlockIndex* pblockindex) @@ -1054,13 +1094,13 @@ static CBlockUndo GetUndoChecked(const CBlockIndex* pblockindex) return blockUndo; } -static UniValue getmerkleblocks(const JSONRPCRequest& request) +static RPCHelpMan getmerkleblocks() { - RPCHelpMan{"getmerkleblocks", + return RPCHelpMan{"getmerkleblocks", "\nReturns an array of hex-encoded merkleblocks for blocks starting from which match .\n", { {"filter", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex-encoded bloom filter"}, - {"hash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The block hash"}, + {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The block hash"}, {"count", RPCArg::Type::NUM, /* default */ strprintf("%s", MAX_HEADERS_RESULTS), ""}, }, RPCResult{ @@ -1070,8 +1110,8 @@ static UniValue getmerkleblocks(const JSONRPCRequest& request) HelpExampleCli("getmerkleblocks", "\"2303028005802040100040000008008400048141010000f8400420800080025004000004130000000000000001\" \"00000000007e1432d2af52e8463278bf556b55cf5049262f25634557e2e91202\" 2000") + HelpExampleRpc("getmerkleblocks", "\"2303028005802040100040000008008400048141010000f8400420800080025004000004130000000000000001\" \"00000000007e1432d2af52e8463278bf556b55cf5049262f25634557e2e91202\" 2000") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ ChainstateManager& chainman = EnsureAnyChainman(request.context); LOCK(cs_main); @@ -1125,11 +1165,13 @@ static UniValue getmerkleblocks(const JSONRPCRequest& request) arrMerkleBlocks.push_back(strHex); } return arrMerkleBlocks; +}, + }; } -static UniValue getblock(const JSONRPCRequest& request) +static RPCHelpMan getblock() { - RPCHelpMan{"getblock", + return RPCHelpMan{"getblock", "\nIf verbosity is 0, returns a string that is serialized, hex-encoded data for block 'hash'.\n" "If verbosity is 1, 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", @@ -1187,8 +1229,8 @@ static UniValue getblock(const JSONRPCRequest& request) HelpExampleCli("getblock", "\"00000000000fd08c2fb661d2fcb0d49abb3a91e5f27082ce64feed3b4dede2e2\"") + HelpExampleRpc("getblock", "\"00000000000fd08c2fb661d2fcb0d49abb3a91e5f27082ce64feed3b4dede2e2\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ uint256 hash(ParseHashV(request.params[0], "blockhash")); int verbosity = 1; @@ -1227,11 +1269,13 @@ static UniValue getblock(const JSONRPCRequest& request) LLMQContext& llmq_ctx = EnsureLLMQContext(node); return blockToJSON(block, tip, pblockindex, *llmq_ctx.clhandler, *llmq_ctx.isman, verbosity >= 2); +}, + }; } -static UniValue pruneblockchain(const JSONRPCRequest& request) +static RPCHelpMan pruneblockchain() { - RPCHelpMan{"pruneblockchain", "", + return RPCHelpMan{"pruneblockchain", "", { {"height", RPCArg::Type::NUM, RPCArg::Optional::NO, "The block height to prune up to. May be set to a discrete height, or to a " + UNIX_EPOCH_TIME + "\n" " to prune blocks whose block time is at least 2 hours older than the provided timestamp."}, @@ -1242,8 +1286,8 @@ static UniValue pruneblockchain(const JSONRPCRequest& request) HelpExampleCli("pruneblockchain", "1000") + HelpExampleRpc("pruneblockchain", "1000") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ if (!fPruneMode) throw JSONRPCError(RPC_MISC_ERROR, "Cannot prune blocks because node is not in prune mode."); @@ -1285,6 +1329,8 @@ static UniValue pruneblockchain(const JSONRPCRequest& request) block = block->pprev; } return uint64_t(block->nHeight); +}, + }; } CoinStatsHashType ParseHashType(const std::string& hash_type_input) @@ -1300,9 +1346,9 @@ CoinStatsHashType ParseHashType(const std::string& hash_type_input) } } -static UniValue gettxoutsetinfo(const JSONRPCRequest& request) +static RPCHelpMan gettxoutsetinfo() { - RPCHelpMan{"gettxoutsetinfo", + return RPCHelpMan{"gettxoutsetinfo", "\nReturns statistics about the unspent transaction output set.\n" "Note this call may take some time if you are not using coinstatsindex.\n", { @@ -1348,8 +1394,8 @@ static UniValue gettxoutsetinfo(const JSONRPCRequest& request) HelpExampleRpc("gettxoutsetinfo", R"("none", 1000)") + HelpExampleRpc("gettxoutsetinfo", R"("none", "00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09")") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ UniValue ret(UniValue::VOBJ); CBlockIndex* pindex{nullptr}; @@ -1439,11 +1485,13 @@ static UniValue gettxoutsetinfo(const JSONRPCRequest& request) throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set"); } return ret; +}, + }; } -static UniValue gettxout(const JSONRPCRequest& request) +static RPCHelpMan gettxout() { - RPCHelpMan{"gettxout", + return RPCHelpMan{"gettxout", "\nReturns details about an unspent transaction output.\n", { {"txid", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction id"}, @@ -1475,7 +1523,8 @@ static UniValue gettxout(const JSONRPCRequest& request) "\nAs a JSON-RPC call\n" + HelpExampleRpc("gettxout", "\"txid\", 1") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ const NodeContext& node = EnsureAnyNodeContext(request.context); @@ -1523,11 +1572,13 @@ static UniValue gettxout(const JSONRPCRequest& request) ret.pushKV("coinbase", (bool)coin.fCoinBase); return ret; +}, + }; } -static UniValue verifychain(const JSONRPCRequest& request) +static RPCHelpMan verifychain() { - RPCHelpMan{"verifychain", + return RPCHelpMan{"verifychain", "\nVerifies blockchain database.\n", { {"checklevel", RPCArg::Type::NUM, /* default */ strprintf("%d, range=0-4", DEFAULT_CHECKLEVEL), @@ -1540,8 +1591,8 @@ static UniValue verifychain(const JSONRPCRequest& request) HelpExampleCli("verifychain", "") + HelpExampleRpc("verifychain", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ const int check_level(request.params[0].isNull() ? DEFAULT_CHECKLEVEL : request.params[0].get_int()); const int check_depth{request.params[1].isNull() ? DEFAULT_CHECKBLOCKS : request.params[1].get_int()}; @@ -1553,6 +1604,8 @@ static UniValue verifychain(const JSONRPCRequest& request) CChainState& active_chainstate = chainman.ActiveChainstate(); return CVerifyDB().VerifyDB( active_chainstate, Params(), active_chainstate.CoinsTip(), *node.evodb, check_level, check_depth); +}, + }; } static void SoftForkDescPushBack(const CBlockIndex* active_chain_tip, UniValue& softforks, const Consensus::Params& params, Consensus::BuriedDeployment dep) @@ -1628,9 +1681,9 @@ static void SoftForkDescPushBack(const CBlockIndex* active_chain_tip, const std: softforks.pushKV(DeploymentName(id), rv); } -UniValue getblockchaininfo(const JSONRPCRequest& request) +RPCHelpMan getblockchaininfo() { - RPCHelpMan{"getblockchaininfo", + return RPCHelpMan{"getblockchaininfo", "Returns an object containing various state info regarding blockchain processing.\n", {}, RPCResult{ @@ -1683,7 +1736,8 @@ UniValue getblockchaininfo(const JSONRPCRequest& request) HelpExampleCli("getblockchaininfo", "") + HelpExampleRpc("getblockchaininfo", "") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ ChainstateManager& chainman = EnsureAnyChainman(request.context); LOCK(cs_main); @@ -1748,6 +1802,8 @@ UniValue getblockchaininfo(const JSONRPCRequest& request) obj.pushKV("warnings", GetWarnings(false).original); return obj; +}, + }; } /** Comparison function for sorting the getchaintips heads. */ @@ -1765,9 +1821,9 @@ struct CompareBlocksByHeight } }; -static UniValue getchaintips(const JSONRPCRequest& request) +static RPCHelpMan getchaintips() { - RPCHelpMan{"getchaintips", + return RPCHelpMan{"getchaintips", "Return information about all known tips in the block tree," " including the main chain as well as orphaned branches.\n", { @@ -1797,7 +1853,8 @@ static UniValue getchaintips(const JSONRPCRequest& request) HelpExampleCli("getchaintips", "") + HelpExampleRpc("getchaintips", "") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ ChainstateManager& chainman = EnsureAnyChainman(request.context); LOCK(cs_main); @@ -1886,6 +1943,8 @@ static UniValue getchaintips(const JSONRPCRequest& request) } return res; +}, + }; } UniValue MempoolInfoToJSON(const CTxMemPool& pool, llmq::CInstantSendManager& isman) @@ -1907,9 +1966,9 @@ UniValue MempoolInfoToJSON(const CTxMemPool& pool, llmq::CInstantSendManager& is return ret; } -static UniValue getmempoolinfo(const JSONRPCRequest& request) +static RPCHelpMan getmempoolinfo() { - RPCHelpMan{"getmempoolinfo", + return RPCHelpMan{"getmempoolinfo", "\nReturns details on the active state of the TX memory pool.\n", {}, RPCResult{ @@ -1930,17 +1989,19 @@ static UniValue getmempoolinfo(const JSONRPCRequest& request) HelpExampleCli("getmempoolinfo", "") + HelpExampleRpc("getmempoolinfo", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ const NodeContext& node = EnsureAnyNodeContext(request.context); const CTxMemPool& mempool = EnsureMemPool(node); LLMQContext& llmq_ctx = EnsureLLMQContext(node); return MempoolInfoToJSON(mempool, *llmq_ctx.isman); +}, + }; } -static UniValue preciousblock(const JSONRPCRequest& request) +static RPCHelpMan preciousblock() { - RPCHelpMan{"preciousblock", + return 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", @@ -1952,8 +2013,8 @@ static UniValue preciousblock(const JSONRPCRequest& request) HelpExampleCli("preciousblock", "\"blockhash\"") + HelpExampleRpc("preciousblock", "\"blockhash\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ uint256 hash(ParseHashV(request.params[0], "blockhash")); CBlockIndex* pblockindex; @@ -1974,11 +2035,13 @@ static UniValue preciousblock(const JSONRPCRequest& request) } return NullUniValue; +}, + }; } -static UniValue invalidateblock(const JSONRPCRequest& request) +static RPCHelpMan invalidateblock() { - RPCHelpMan{"invalidateblock", + return RPCHelpMan{"invalidateblock", "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n", { {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hash of the block to mark as invalid"}, @@ -1988,8 +2051,8 @@ static UniValue invalidateblock(const JSONRPCRequest& request) HelpExampleCli("invalidateblock", "\"blockhash\"") + HelpExampleRpc("invalidateblock", "\"blockhash\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ uint256 hash(ParseHashV(request.params[0], "blockhash")); BlockValidationState state; @@ -2015,11 +2078,13 @@ static UniValue invalidateblock(const JSONRPCRequest& request) } return NullUniValue; +}, + }; } -static UniValue reconsiderblock(const JSONRPCRequest& request) +static RPCHelpMan reconsiderblock() { - RPCHelpMan{"reconsiderblock", + return RPCHelpMan{"reconsiderblock", "\nRemoves invalidity status of a block, its ancestors and its descendants, reconsider them for activation.\n" "This can be used to undo the effects of invalidateblock.\n", { @@ -2030,8 +2095,8 @@ static UniValue reconsiderblock(const JSONRPCRequest& request) HelpExampleCli("reconsiderblock", "\"blockhash\"") + HelpExampleRpc("reconsiderblock", "\"blockhash\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ ChainstateManager& chainman = EnsureAnyChainman(request.context); CChainState& active_chainstate = chainman.ActiveChainstate(); @@ -2055,11 +2120,13 @@ static UniValue reconsiderblock(const JSONRPCRequest& request) } return NullUniValue; +}, + }; } -static UniValue getchaintxstats(const JSONRPCRequest& request) +static RPCHelpMan getchaintxstats() { - RPCHelpMan{"getchaintxstats", + return RPCHelpMan{"getchaintxstats", "\nCompute statistics about the total number and rate of transactions in the chain.\n", { {"nblocks", RPCArg::Type::NUM, /* default */ "one month", "Size of the window in number of blocks"}, @@ -2081,8 +2148,8 @@ static UniValue getchaintxstats(const JSONRPCRequest& request) HelpExampleCli("getchaintxstats", "") + HelpExampleRpc("getchaintxstats", "2016") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ ChainstateManager& chainman = EnsureAnyChainman(request.context); CChain& active_chain = chainman.ActiveChain(); @@ -2135,6 +2202,8 @@ static UniValue getchaintxstats(const JSONRPCRequest& request) } return ret; +}, + }; } template @@ -2193,9 +2262,9 @@ static inline bool SetHasKeys(const std::set& set, const Tk& key, const Args& // outpoint (needed for the utxo index) + nHeight + fCoinBase static constexpr size_t PER_UTXO_OVERHEAD = sizeof(COutPoint) + sizeof(uint32_t) + sizeof(bool); -static UniValue getblockstats(const JSONRPCRequest& request) +static RPCHelpMan getblockstats() { - RPCHelpMan{"getblockstats", + return RPCHelpMan{"getblockstats", "\nCompute per block statistics for a given window. All amounts are in duffs.\n" "It won't work for some heights with pruning.\n", { @@ -2249,8 +2318,8 @@ static UniValue getblockstats(const JSONRPCRequest& request) HelpExampleRpc("getblockstats", R"("00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09", ["minfeerate","avgfeerate"])") + HelpExampleRpc("getblockstats", R"(1000, ["minfeerate","avgfeerate"])") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ if (g_txindex) { g_txindex->BlockUntilSyncedToCurrentChain(); } @@ -2405,11 +2474,13 @@ static UniValue getblockstats(const JSONRPCRequest& request) ret.pushKV(stat, value); } return ret; +}, + }; } -static UniValue getspecialtxes(const JSONRPCRequest& request) +static RPCHelpMan getspecialtxes() { - RPCHelpMan{"getspecialtxes", + return RPCHelpMan{"getspecialtxes", "Returns an array of special transactions found in the specified block\n" "\nIf verbosity is 0, returns tx hash for each transaction.\n" "If verbosity is 1, returns hex-encoded data for each transaction.\n" @@ -2436,8 +2507,8 @@ static UniValue getspecialtxes(const JSONRPCRequest& request) HelpExampleCli("getspecialtxes", "\"00000000000fd08c2fb661d2fcb0d49abb3a91e5f27082ce64feed3b4dede2e2\"") + HelpExampleRpc("getspecialtxes", "\"00000000000fd08c2fb661d2fcb0d49abb3a91e5f27082ce64feed3b4dede2e2\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ const NodeContext& node = EnsureAnyNodeContext(request.context); ChainstateManager& chainman = EnsureChainman(node); @@ -2510,13 +2581,14 @@ static UniValue getspecialtxes(const JSONRPCRequest& request) default : throw JSONRPCError(RPC_INTERNAL_ERROR, "Unsupported verbosity"); } } - return result; +}, + }; } -static UniValue savemempool(const JSONRPCRequest& request) +static RPCHelpMan savemempool() { - RPCHelpMan{"savemempool", + return RPCHelpMan{"savemempool", "\nDumps the mempool to disk. It will fail until the previous dump is fully loaded.\n", {}, RPCResult{RPCResult::Type::NONE, "", ""}, @@ -2524,8 +2596,8 @@ static UniValue savemempool(const JSONRPCRequest& request) HelpExampleCli("savemempool", "") + HelpExampleRpc("savemempool", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ const CTxMemPool& mempool = EnsureAnyMemPool(request.context); if (!mempool.IsLoaded()) { @@ -2537,6 +2609,8 @@ static UniValue savemempool(const JSONRPCRequest& request) } return NullUniValue; +}, + }; } namespace { @@ -2600,9 +2674,9 @@ class CoinsViewScanReserver } }; -UniValue scantxoutset(const JSONRPCRequest& request) +static RPCHelpMan scantxoutset() { - RPCHelpMan{"scantxoutset", + return 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" @@ -2656,8 +2730,8 @@ UniValue scantxoutset(const JSONRPCRequest& request) {RPCResult::Type::STR_AMOUNT, "total_amount", "The total amount of all found unspent outputs in " + CURRENCY_UNIT}, }}, RPCExamples{""}, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR}); UniValue result(UniValue::VOBJ); @@ -2751,11 +2825,13 @@ UniValue scantxoutset(const JSONRPCRequest& request) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid command"); } return result; +}, + }; } -static UniValue getblockfilter(const JSONRPCRequest& request) +static RPCHelpMan getblockfilter() { - RPCHelpMan{"getblockfilter", + return RPCHelpMan{"getblockfilter", "\nRetrieve a BIP 157 content filter for a particular block.\n", { {"blockhash", RPCArg::Type::STR, RPCArg::Optional::NO, "The hash of the block"}, @@ -2771,8 +2847,8 @@ static UniValue getblockfilter(const JSONRPCRequest& request) HelpExampleCli("getblockfilter", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\" \"basic\"")+ HelpExampleRpc("getblockfilter", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\", \"basic\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ uint256 block_hash(ParseHashV(request.params[0], "blockhash")); std::string filtertype_name = "basic"; if (!request.params[1].isNull()) { @@ -2828,6 +2904,8 @@ static UniValue getblockfilter(const JSONRPCRequest& request) ret.pushKV("filter", HexStr(filter.GetEncodedFilter())); ret.pushKV("header", filter_header.GetHex()); return ret; +}, + }; } /** @@ -2835,9 +2913,9 @@ static UniValue getblockfilter(const JSONRPCRequest& request) * * @see SnapshotMetadata */ -UniValue dumptxoutset(const JSONRPCRequest& request) +static RPCHelpMan dumptxoutset() { - RPCHelpMan{ + return RPCHelpMan{ "dumptxoutset", "Write the serialized UTXO set to disk.", { @@ -2854,9 +2932,9 @@ UniValue dumptxoutset(const JSONRPCRequest& request) }, RPCExamples{ HelpExampleCli("dumptxoutset", "utxo.dat") - } - }.Check(request); - + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ const fs::path path = fsbridge::AbsPathJoin(GetDataDir(), request.params[0].get_str()); // Write to a temporary path and then move into `path` on completion // to avoid confusion due to an interruption. @@ -2877,6 +2955,8 @@ UniValue dumptxoutset(const JSONRPCRequest& request) result.pushKV("path", path.string()); return result; +}, + }; } UniValue CreateUTXOSnapshot(NodeContext& node, CChainState& chainstate, CAutoFile& afile) @@ -2986,8 +3066,7 @@ static const CRPCCommand commands[] = { "hidden", "dumptxoutset", &dumptxoutset, {"path"} }, }; // clang-format on - - for (const auto& command : commands) { - t.appendCommand(command.name, &command); + for (const auto& c : commands) { + t.appendCommand(c.name, &c); } } diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index d787647bb64d..4645854ba6ac 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -109,7 +109,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "gettransaction", 1, "include_watchonly" }, { "gettransaction", 2, "verbose" }, { "getrawtransaction", 1, "verbose" }, - { "getrawtransactionmulti", 0, "txid_map" }, + { "getrawtransactionmulti", 0, "transactions" }, { "getrawtransactionmulti", 1, "verbose" }, { "gettxchainlocks", 0, "txids" }, { "createrawtransaction", 0, "inputs" }, @@ -179,11 +179,11 @@ static const CRPCConvertParam vRPCConvertParams[] = { "logging", 0, "include" }, { "logging", 1, "exclude" }, { "sporkupdate", 1, "value" }, - { "voteraw", 1, "tx_index" }, + { "voteraw", 1, "mn-collateral-tx-index" }, { "voteraw", 5, "time" }, { "getblockhashes", 0, "high"}, { "getblockhashes", 1, "low" }, - { "getspentinfo", 0, "json" }, + { "getspentinfo", 0, "request" }, { "getaddresstxids", 0, "addresses" }, { "getaddressbalance", 0, "addresses" }, { "getaddressdeltas", 0, "addresses" }, diff --git a/src/rpc/coinjoin.cpp b/src/rpc/coinjoin.cpp index ae85b1c8376a..b4b615ff97d7 100644 --- a/src/rpc/coinjoin.cpp +++ b/src/rpc/coinjoin.cpp @@ -21,9 +21,9 @@ #include #ifdef ENABLE_WALLET -static UniValue coinjoin(const JSONRPCRequest& request) +static RPCHelpMan coinjoin() { - RPCHelpMan{"coinjoin", + return RPCHelpMan{"coinjoin", "\nAvailable commands:\n" " start - Start mixing\n" " stop - Stop mixing\n" @@ -33,8 +33,8 @@ static UniValue coinjoin(const JSONRPCRequest& request) }, RPCResults{}, RPCExamples{""}, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; @@ -83,23 +83,28 @@ static UniValue coinjoin(const JSONRPCRequest& request) } return "Unknown command, please see \"help coinjoin\""; +}, + }; } #endif // ENABLE_WALLET -static UniValue getpoolinfo(const JSONRPCRequest& request) +static RPCHelpMan getpoolinfo() { - throw std::runtime_error( - RPCHelpMan{"getpoolinfo", + return RPCHelpMan{"getpoolinfo", "DEPRECATED. Please use getcoinjoininfo instead.\n", {}, RPCResults{}, - RPCExamples{""}} - .ToString()); + RPCExamples{""}, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ + throw JSONRPCError(RPC_METHOD_DEPRECATED, "Please use getcoinjoininfo instead"); +}, + }; } -static UniValue getcoinjoininfo(const JSONRPCRequest& request) +static RPCHelpMan getcoinjoininfo() { - RPCHelpMan{"getcoinjoininfo", + return RPCHelpMan{"getcoinjoininfo", "Returns an object containing an information about CoinJoin settings and state.\n", {}, { @@ -143,8 +148,8 @@ static UniValue getcoinjoininfo(const JSONRPCRequest& request) HelpExampleCli("getcoinjoininfo", "") + HelpExampleRpc("getcoinjoininfo", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ UniValue obj(UniValue::VOBJ); const NodeContext& node = EnsureAnyNodeContext(request.context); @@ -173,7 +178,10 @@ static UniValue getcoinjoininfo(const JSONRPCRequest& request) #endif // ENABLE_WALLET return obj; +}, + }; } + void RegisterCoinJoinRPCCommands(CRPCTable &t) { // clang-format off @@ -183,7 +191,7 @@ static const CRPCCommand commands[] = { "dash", "getpoolinfo", &getpoolinfo, {} }, { "dash", "getcoinjoininfo", &getcoinjoininfo, {} }, #ifdef ENABLE_WALLET - { "dash", "coinjoin", &coinjoin, {} }, + { "dash", "coinjoin", &coinjoin, {"command"} }, #endif // ENABLE_WALLET }; // clang-format on diff --git a/src/rpc/evo.cpp b/src/rpc/evo.cpp index c5a4a75b1266..69b19c9c6524 100644 --- a/src/rpc/evo.cpp +++ b/src/rpc/evo.cpp @@ -35,8 +35,8 @@ #endif//ENABLE_WALLET #ifdef ENABLE_WALLET -extern UniValue signrawtransaction(const JSONRPCRequest& request); -extern UniValue sendrawtransaction(const JSONRPCRequest& request); +extern RPCHelpMan signrawtransaction(); +extern RPCHelpMan sendrawtransaction(); #else class CWallet; #endif//ENABLE_WALLET @@ -341,7 +341,7 @@ static std::string SignAndSendSpecialTx(const JSONRPCRequest& request, const Cha JSONRPCRequest signRequest(request); signRequest.params.setArray(); signRequest.params.push_back(HexStr(ds)); - UniValue signResult = signrawtransactionwithwallet(signRequest); + UniValue signResult = signrawtransactionwithwallet().HandleRequest(signRequest); if (!fSubmit) { return signResult["hex"].get_str(); @@ -350,7 +350,7 @@ static std::string SignAndSendSpecialTx(const JSONRPCRequest& request, const Cha JSONRPCRequest sendRequest(request); sendRequest.params.setArray(); sendRequest.params.push_back(signResult["hex"].get_str()); - return sendrawtransaction(sendRequest).get_str(); + return sendrawtransaction().HandleRequest(sendRequest).get_str(); } static void protx_register_fund_help(const JSONRPCRequest& request, bool legacy) diff --git a/src/rpc/governance.cpp b/src/rpc/governance.cpp index 101e70c524f1..1f0e34feb28b 100644 --- a/src/rpc/governance.cpp +++ b/src/rpc/governance.cpp @@ -1097,7 +1097,7 @@ static const CRPCCommand commands[] = { "dash", "getgovernanceinfo", &getgovernanceinfo, {} }, { "dash", "getsuperblockbudget", &getsuperblockbudget, {"index"} }, { "dash", "gobject", &gobject, {} }, - { "dash", "voteraw", &voteraw, {"tx_hash","tx_index","gov_hash","signal","outcome","time","sig"} }, + { "dash", "voteraw", &voteraw, {"mn-collateral-tx-hash","mn-collateral-tx-index","governance-hash","vote-signal","vote-outcome","time","vote-sig"} }, }; // clang-format on diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 43f4f687195c..6b707a777a72 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -94,9 +94,9 @@ static UniValue GetNetworkHashPS(int lookup, int height, const CChain& active_ch return workDiff.getdouble() / timeDiff; } -static UniValue getnetworkhashps(const JSONRPCRequest& request) +static RPCHelpMan getnetworkhashps() { - RPCHelpMan{"getnetworkhashps", + return 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", @@ -110,11 +110,14 @@ static UniValue getnetworkhashps(const JSONRPCRequest& request) HelpExampleCli("getnetworkhashps", "") + HelpExampleRpc("getnetworkhashps", "") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ ChainstateManager& chainman = EnsureAnyChainman(request.context); LOCK(cs_main); return GetNetworkHashPS(!request.params[0].isNull() ? request.params[0].get_int() : 120, !request.params[1].isNull() ? request.params[1].get_int() : -1, chainman.ActiveChain()); +}, + }; } #if ENABLE_MINER @@ -218,9 +221,9 @@ static bool getScriptFromDescriptor(const std::string& descriptor, CScript& scri } } -static UniValue generatetodescriptor(const JSONRPCRequest& request) +static RPCHelpMan generatetodescriptor() { - RPCHelpMan{ + return RPCHelpMan{ "generatetodescriptor", "\nMine blocks immediately to a specified descriptor (before the RPC call returns)\n", { @@ -236,9 +239,8 @@ static UniValue generatetodescriptor(const JSONRPCRequest& request) }, RPCExamples{ "\nGenerate 11 blocks to mydesc\n" + HelpExampleCli("generatetodescriptor", "11 \"mydesc\"")}, - } - .Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ const int num_blocks{request.params[0].get_int()}; const uint64_t max_tries{request.params[2].isNull() ? DEFAULT_MAX_TRIES : request.params[2].get_int()}; @@ -254,11 +256,13 @@ static UniValue generatetodescriptor(const JSONRPCRequest& request) LLMQContext& llmq_ctx = EnsureLLMQContext(node); return generateBlocks(chainman, *node.evodb, *node.chain_helper, llmq_ctx, mempool, coinbase_script, num_blocks, max_tries); +}, + }; } -static UniValue generatetoaddress(const JSONRPCRequest& request) +static RPCHelpMan generatetoaddress() { - RPCHelpMan{"generatetoaddress", + return RPCHelpMan{"generatetoaddress", "\nMine blocks immediately to a specified address (before the RPC call returns)\n", { {"nblocks", RPCArg::Type::NUM, RPCArg::Optional::NO, "How many blocks are generated immediately."}, @@ -275,8 +279,8 @@ static UniValue generatetoaddress(const JSONRPCRequest& request) + HelpExampleCli("generatetoaddress", "11 \"myaddress\"") + "If you are using the " PACKAGE_NAME " wallet, you can get a new address to send the newly generated coins to with:\n" + HelpExampleCli("getnewaddress", "")}, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ const int num_blocks{request.params[0].get_int()}; const uint64_t max_tries{request.params[2].isNull() ? DEFAULT_MAX_TRIES : request.params[2].get_int()}; @@ -293,34 +297,36 @@ static UniValue generatetoaddress(const JSONRPCRequest& request) CScript coinbase_script = GetScriptForDestination(destination); return generateBlocks(chainman, *node.evodb, *node.chain_helper, llmq_ctx, mempool, coinbase_script, num_blocks, max_tries); +}, + }; } -static UniValue generateblock(const JSONRPCRequest& request) +static RPCHelpMan generateblock() { - RPCHelpMan{"generateblock", + return RPCHelpMan{"generateblock", "\nMine a block with a set of ordered transactions immediately to a specified address or descriptor (before the RPC call returns)\n", { - {"address/descriptor", RPCArg::Type::STR, RPCArg::Optional::NO, "The address or descriptor to send the newly generated coins to."}, + {"output", RPCArg::Type::STR, RPCArg::Optional::NO, "The address or descriptor to send the newly generated coins to."}, {"transactions", RPCArg::Type::ARR, RPCArg::Optional::NO, "An array of hex strings which are either txids or raw transactions.\n" "Txids must reference transactions currently in the mempool.\n" "All transactions must be valid and in valid order, otherwise the block will be rejected.", { {"rawtx/txid", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, ""}, }, - } + }, }, RPCResult{ RPCResult::Type::OBJ, "", "", { - {RPCResult::Type::STR_HEX, "hash", "hash of generated block"} + {RPCResult::Type::STR_HEX, "hash", "hash of generated block"}, } }, RPCExamples{ "\nGenerate a block to myaddress, with txs rawtx and mempool_txid\n" + HelpExampleCli("generateblock", R"("myaddress" '["rawtx", "mempool_txid"]')") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ const auto address_or_descriptor = request.params[0].get_str(); CScript coinbase_script; std::string error; @@ -405,6 +411,8 @@ static UniValue generateblock(const JSONRPCRequest& request) UniValue obj(UniValue::VOBJ); obj.pushKV("hash", block_hash.GetHex()); return obj; +}, + }; } #else static UniValue generatetoaddress(const JSONRPCRequest& request) @@ -421,9 +429,21 @@ static UniValue generateblock(const JSONRPCRequest& request) } #endif // ENABLE_MINER -static UniValue getmininginfo(const JSONRPCRequest& request) +static RPCHelpMan generate() { - RPCHelpMan{"getmininginfo", + 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()); + } + }}; +} + +static RPCHelpMan getmininginfo() +{ + return RPCHelpMan{"getmininginfo", "\nReturns a json object containing mining-related information.", {}, RPCResult{ @@ -442,7 +462,8 @@ static UniValue getmininginfo(const JSONRPCRequest& request) HelpExampleCli("getmininginfo", "") + HelpExampleRpc("getmininginfo", "") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ const NodeContext& node = EnsureAnyNodeContext(request.context); @@ -457,18 +478,20 @@ static UniValue getmininginfo(const JSONRPCRequest& request) if (BlockAssembler::m_last_block_size) obj.pushKV("currentblocksize", *BlockAssembler::m_last_block_size); if (BlockAssembler::m_last_block_num_txs) obj.pushKV("currentblocktx", *BlockAssembler::m_last_block_num_txs); obj.pushKV("difficulty", (double)GetDifficulty(active_chain.Tip())); - obj.pushKV("networkhashps", getnetworkhashps(request)); + obj.pushKV("networkhashps", getnetworkhashps().HandleRequest(request)); obj.pushKV("pooledtx", (uint64_t)mempool.size()); obj.pushKV("chain", Params().NetworkIDString()); obj.pushKV("warnings", GetWarnings(false).original); return obj; +}, + }; } // NOTE: Unlike wallet RPC (which use BTC values), mining RPCs follow GBT (BIP 22) in using satoshi amounts -static UniValue prioritisetransaction(const JSONRPCRequest& request) +static RPCHelpMan prioritisetransaction() { - RPCHelpMan{"prioritisetransaction", + return RPCHelpMan{"prioritisetransaction", "Accepts the transaction into mined blocks at a higher (or lower) priority\n", { {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id."}, @@ -483,8 +506,9 @@ static UniValue prioritisetransaction(const JSONRPCRequest& request) HelpExampleCli("prioritisetransaction", "\"txid\" 10000") + HelpExampleRpc("prioritisetransaction", "\"txid\", 10000") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ LOCK(cs_main); uint256 hash(ParseHashV(request.params[0].get_str(), "txid")); @@ -492,6 +516,8 @@ static UniValue prioritisetransaction(const JSONRPCRequest& request) EnsureAnyMemPool(request.context).PrioritiseTransaction(hash, nAmount); return true; +}, + }; } @@ -523,9 +549,9 @@ static std::string gbt_vb_name(const Consensus::DeploymentPos pos) { return s; } -static UniValue getblocktemplate(const JSONRPCRequest& request) +static RPCHelpMan getblocktemplate() { - RPCHelpMan{"getblocktemplate", + return 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, and 9:\n" @@ -629,8 +655,8 @@ static UniValue getblocktemplate(const JSONRPCRequest& request) HelpExampleCli("getblocktemplate", "") + HelpExampleRpc("getblocktemplate", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ const NodeContext& node = EnsureAnyNodeContext(request.context); ChainstateManager& chainman = EnsureChainman(node); @@ -957,6 +983,8 @@ static UniValue getblocktemplate(const JSONRPCRequest& request) result.pushKV("coinbase_payload", HexStr(pblock->vtx[0]->vExtraPayload)); return result; +}, + }; } class submitblock_StateCatcher final : public CValidationInterface @@ -977,10 +1005,10 @@ class submitblock_StateCatcher final : public CValidationInterface } }; -static UniValue submitblock(const JSONRPCRequest& request) +static RPCHelpMan submitblock() { // We allow 2 arguments for compliance with BIP22. Argument 2 is ignored. - RPCHelpMan{"submitblock", + return RPCHelpMan{"submitblock", "\nAttempts to submit new block to network.\n" "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n", { @@ -992,8 +1020,8 @@ static UniValue submitblock(const JSONRPCRequest& request) HelpExampleCli("submitblock", "\"mydata\"") + HelpExampleRpc("submitblock", "\"mydata\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr blockptr = std::make_shared(); CBlock& block = *blockptr; if (!DecodeHexBlk(block, request.params[0].get_str())) { @@ -1031,11 +1059,13 @@ static UniValue submitblock(const JSONRPCRequest& request) return "inconclusive"; } return BIP22ValidationResult(sc->state); +}, + }; } -static UniValue submitheader(const JSONRPCRequest& request) +static RPCHelpMan submitheader() { - RPCHelpMan{"submitheader", + return 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", { @@ -1047,8 +1077,8 @@ static UniValue submitheader(const JSONRPCRequest& request) HelpExampleCli("submitheader", "\"aabbcc\"") + HelpExampleRpc("submitheader", "\"aabbcc\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ CBlockHeader h; if (!DecodeHexBlockHeader(h, request.params[0].get_str())) { throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block header decode failed"); @@ -1068,11 +1098,13 @@ static UniValue submitheader(const JSONRPCRequest& request) throw JSONRPCError(RPC_VERIFY_ERROR, state.ToString()); } throw JSONRPCError(RPC_VERIFY_ERROR, state.GetRejectReason()); +}, + }; } -static UniValue estimatesmartfee(const JSONRPCRequest& request) +static RPCHelpMan estimatesmartfee() { - RPCHelpMan{"estimatesmartfee", + return RPCHelpMan{"estimatesmartfee", "\nEstimates the approximate fee per kilobyte needed for a transaction to begin\n" "confirmation within conf_target blocks if possible and return the number of blocks\n" "for which the estimate is valid.\n", @@ -1103,8 +1135,8 @@ static UniValue estimatesmartfee(const JSONRPCRequest& request) RPCExamples{ HelpExampleCli("estimatesmartfee", "6") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ RPCTypeCheck(request.params, {UniValue::VNUM, UniValue::VSTR}); RPCTypeCheckArgument(request.params[0], UniValue::VNUM); @@ -1133,11 +1165,13 @@ static UniValue estimatesmartfee(const JSONRPCRequest& request) } result.pushKV("blocks", feeCalc.returnedTarget); return result; +}, + }; } -static UniValue estimaterawfee(const JSONRPCRequest& request) +static RPCHelpMan estimaterawfee() { - RPCHelpMan{"estimaterawfee", + return RPCHelpMan{"estimaterawfee", "\nWARNING: This interface is unstable and may disappear or change!\n" "\nWARNING: This is an advanced API call that is tightly coupled to the specific\n" " implementation of fee estimation. The parameters it can be called with\n" @@ -1188,8 +1222,8 @@ static UniValue estimaterawfee(const JSONRPCRequest& request) RPCExamples{ HelpExampleCli("estimaterawfee", "6 0.9") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ RPCTypeCheck(request.params, {UniValue::VNUM, UniValue::VNUM}, true); RPCTypeCheckArgument(request.params[0], UniValue::VNUM); @@ -1251,6 +1285,8 @@ static UniValue estimaterawfee(const JSONRPCRequest& request) result.pushKV(StringForFeeEstimateHorizon(horizon), horizon_result); } return result; +}, + }; } void RegisterMiningRPCCommands(CRPCTable &t) @@ -1269,7 +1305,7 @@ static const CRPCCommand commands[] = #if ENABLE_MINER { "generating", "generatetoaddress", &generatetoaddress, {"nblocks","address","maxtries"} }, { "generating", "generatetodescriptor", &generatetodescriptor, {"num_blocks","descriptor","maxtries"} }, - { "generating", "generateblock", &generateblock, {"address","transactions"} }, + { "generating", "generateblock", &generateblock, {"output","transactions"} }, #else { "hidden", "generatetoaddress", &generatetoaddress, {"nblocks","address","maxtries"} }, // Hidden as it isn't functional, just an error to let people know if miner isn't compiled { "hidden", "generatetodescriptor", &generatetodescriptor, {"num_blocks","descriptor","maxtries"} }, @@ -1279,10 +1315,10 @@ static const CRPCCommand commands[] = { "util", "estimatesmartfee", &estimatesmartfee, {"conf_target", "estimate_mode"} }, { "hidden", "estimaterawfee", &estimaterawfee, {"conf_target", "threshold"} }, + { "hidden", "generate", &generate, {} }, }; // clang-format on - - for (const auto& command : commands) { - t.appendCommand(command.name, &command); + for (const auto& c : commands) { + t.appendCommand(c.name, &c); } } diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 0d11f930202d..dfb463eb3aa7 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -40,9 +40,9 @@ #include -static UniValue debug(const JSONRPCRequest& request) +static RPCHelpMan debug() { - RPCHelpMan{"debug", + return RPCHelpMan{"debug", "Change debug category on the fly. Specify single category or use '+' to specify many.\n" "The valid logging categories are: " + LogInstance().LogCategoriesString() + ".\n" "libevent logging is configured on startup and cannot be modified by this RPC during runtime.\n" @@ -60,7 +60,9 @@ static UniValue debug(const JSONRPCRequest& request) RPCExamples { HelpExampleCli("debug", "dash") + HelpExampleRpc("debug", "dash+net") - }}.Check(request); + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::string strMode = request.params[0].get_str(); LogInstance().DisableCategory(BCLog::ALL); @@ -73,11 +75,13 @@ static UniValue debug(const JSONRPCRequest& request) } return "Debug mode: " + LogInstance().LogCategoriesString(/*enabled_only=*/true); +}, + }; } -static UniValue mnsync(const JSONRPCRequest& request) +static RPCHelpMan mnsync() { - RPCHelpMan{"mnsync", + return RPCHelpMan{"mnsync", "Returns the sync status, updates to the next step or resets it entirely.\n", { {"mode", RPCArg::Type::STR, RPCArg::Optional::NO, "[status|next|reset]"}, @@ -97,7 +101,8 @@ static UniValue mnsync(const JSONRPCRequest& request) RPCResult::Type::STR, "", ""}, }, RPCExamples{""}, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::string strMode = request.params[0].get_str(); @@ -127,15 +132,17 @@ static UniValue mnsync(const JSONRPCRequest& request) return "success"; } return "failure"; +}, + }; } /* Used for updating/reading spork settings on the network */ -static UniValue spork(const JSONRPCRequest& request) +static RPCHelpMan spork() { // default help, for basic mode - RPCHelpMan{"spork", + return RPCHelpMan{"spork", "\nShows information about current state of sporks\n", { {"command", RPCArg::Type::STR, RPCArg::Optional::NO, "'show' to show all current spork values, 'active' to show which sporks are active"}, @@ -155,8 +162,9 @@ static UniValue spork(const JSONRPCRequest& request) RPCExamples { HelpExampleCli("spork", "show") + HelpExampleRpc("spork", "\"show\"") - } - }.Check(request); + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ // basic mode, show info std:: string strCommand = request.params[0].get_str(); @@ -176,11 +184,13 @@ static UniValue spork(const JSONRPCRequest& request) } return NullUniValue; +}, + }; } -static UniValue sporkupdate(const JSONRPCRequest& request) +static RPCHelpMan sporkupdate() { - RPCHelpMan{"sporkupdate", + return RPCHelpMan{"sporkupdate", "\nUpdate the value of the specific spork. Requires \"-sporkkey\" to be set to sign the message.\n", { {"name", RPCArg::Type::STR, RPCArg::Optional::NO, "The name of the spork to update"}, @@ -193,7 +203,8 @@ static UniValue sporkupdate(const JSONRPCRequest& request) HelpExampleCli("sporkupdate", "SPORK_2_INSTANTSEND_ENABLED 4070908800") + HelpExampleRpc("sporkupdate", "\"SPORK_2_INSTANTSEND_ENABLED\", 4070908800") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ // advanced mode, update spork values SporkId nSporkID = CSporkManager::GetSporkIDByName(request.params[0].get_str()); @@ -215,11 +226,13 @@ static UniValue sporkupdate(const JSONRPCRequest& request) } return NullUniValue; +}, + }; } -static UniValue validateaddress(const JSONRPCRequest& request) +static RPCHelpMan validateaddress() { - RPCHelpMan{"validateaddress", + return RPCHelpMan{"validateaddress", "\nReturn information about the given Dash address.\n", { {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The Dash address to validate"}, @@ -238,8 +251,8 @@ static UniValue validateaddress(const JSONRPCRequest& request) HelpExampleCli("validateaddress", "\"" + EXAMPLE_ADDRESS[0] + "\"") + HelpExampleRpc("validateaddress", "\"" + EXAMPLE_ADDRESS[0] + "\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::string error_msg; CTxDestination dest = DecodeDestination(request.params[0].get_str(), error_msg); const bool isValid = IsValidDestination(dest); @@ -261,11 +274,13 @@ static UniValue validateaddress(const JSONRPCRequest& request) } return ret; +}, + }; } -static UniValue createmultisig(const JSONRPCRequest& request) +static RPCHelpMan createmultisig() { - RPCHelpMan{"createmultisig", + return RPCHelpMan{"createmultisig", "\nCreates a multi-signature address with n signature of m keys required.\n" "It returns a json object with the address and redeemScript.\n", { @@ -289,8 +304,8 @@ static UniValue createmultisig(const JSONRPCRequest& request) "\nAs a JSON-RPC call\n" + HelpExampleRpc("createmultisig", "2, \"[\\\"03789ed0bb717d88f7d321a368d905e7430207ebbd82bd342cf11ae157a7ace5fd\\\",\\\"03dbc6764b8884a92e871274b87583e6d5c2a58819473e17e107ef3f6aa5a61626\\\"]\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ int required = request.params[0].get_int(); // Get the public keys @@ -318,11 +333,13 @@ static UniValue createmultisig(const JSONRPCRequest& request) result.pushKV("descriptor", descriptor->ToString()); return result; +}, + }; } -UniValue getdescriptorinfo(const JSONRPCRequest& request) +static RPCHelpMan getdescriptorinfo() { - RPCHelpMan{"getdescriptorinfo", + return RPCHelpMan{"getdescriptorinfo", {"\nAnalyses a descriptor.\n"}, { {"descriptor", RPCArg::Type::STR, RPCArg::Optional::NO, "The descriptor"}, @@ -340,8 +357,9 @@ UniValue getdescriptorinfo(const JSONRPCRequest& request) RPCExamples{ "\nAnalyse a descriptor\n" + HelpExampleCli("getdescriptorinfo", "\"pkh([d34db33f/84h/0h/0h]0279be667ef9dcbbac55a06295Ce870b07029Bfcdb2dce28d959f2815b16f81798)\"") - } - }.Check(request); + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ RPCTypeCheck(request.params, {UniValue::VSTR}); @@ -359,11 +377,13 @@ UniValue getdescriptorinfo(const JSONRPCRequest& request) result.pushKV("issolvable", desc->IsSolvable()); result.pushKV("hasprivatekeys", provider.keys.size() > 0); return result; +}, + }; } -UniValue deriveaddresses(const JSONRPCRequest& request) +static RPCHelpMan deriveaddresses() { - RPCHelpMan{"deriveaddresses", + return RPCHelpMan{"deriveaddresses", "\nDerives one or more addresses corresponding to an output descriptor.\n" "Examples of output descriptors are:\n" " pkh() P2PKH outputs for the given pubkey\n" @@ -385,8 +405,9 @@ UniValue deriveaddresses(const JSONRPCRequest& request) RPCExamples{ "\nFirst three receive addresses\n" + HelpExampleCli("deriveaddresses", "\"pkh([d34db33f/84h/0h/0h]xpub6DJ2dNUysrn5Vt36jH2KLBT2i1auw1tTSSomg8PhqNiUtx8QX2SvC9nrHu81fT41fvDUnhMjEzQgXnQjKEu3oaqMSzhSrHMxyyoEAmUHQbY/0/*)#cjjspncu\" \"[0,2]\"") - } - }.Check(request); + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ RPCTypeCheck(request.params, {UniValue::VSTR, UniValueType()}); // Range argument is checked later const std::string desc_str = request.params[0].get_str(); @@ -438,11 +459,13 @@ UniValue deriveaddresses(const JSONRPCRequest& request) } return addresses; +}, + }; } -static UniValue verifymessage(const JSONRPCRequest& request) +static RPCHelpMan verifymessage() { - RPCHelpMan{"verifymessage", + return RPCHelpMan{"verifymessage", "\nVerify a signed message\n", { {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The Dash address to use for the signature."}, @@ -462,7 +485,8 @@ static UniValue verifymessage(const JSONRPCRequest& request) "\nAs a JSON-RPC call\n" + HelpExampleRpc("verifymessage", "\"" + EXAMPLE_ADDRESS[0] + "\", \"signature\", \"my message\"") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ LOCK(cs_main); @@ -485,11 +509,13 @@ static UniValue verifymessage(const JSONRPCRequest& request) } return false; +}, + }; } -static UniValue signmessagewithprivkey(const JSONRPCRequest& request) +static RPCHelpMan signmessagewithprivkey() { - RPCHelpMan{"signmessagewithprivkey", + return RPCHelpMan{"signmessagewithprivkey", "\nSign a message with the private key of an address\n", { {"privkey", RPCArg::Type::STR, RPCArg::Optional::NO, "The private key to sign the message with."}, @@ -506,7 +532,8 @@ static UniValue signmessagewithprivkey(const JSONRPCRequest& request) "\nAs a JSON-RPC call\n" + HelpExampleRpc("signmessagewithprivkey", "\"privkey\", \"my message\"") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::string strPrivkey = request.params[0].get_str(); std::string strMessage = request.params[1].get_str(); @@ -523,11 +550,13 @@ static UniValue signmessagewithprivkey(const JSONRPCRequest& request) } return signature; +}, + }; } -static UniValue setmocktime(const JSONRPCRequest& request) +static RPCHelpMan setmocktime() { - RPCHelpMan{"setmocktime", + return RPCHelpMan{"setmocktime", "\nSet the local time to given timestamp (-regtest only)\n", { {"timestamp", RPCArg::Type::NUM, RPCArg::Optional::NO, UNIX_EPOCH_TIME + "\n" @@ -535,7 +564,8 @@ static UniValue setmocktime(const JSONRPCRequest& request) }, RPCResult{RPCResult::Type::NONE, "", ""}, RPCExamples{""}, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ if (!Params().IsMockableChain()) { throw std::runtime_error("setmocktime is for regression testing (-regtest mode) only"); @@ -561,11 +591,13 @@ static UniValue setmocktime(const JSONRPCRequest& request) } return NullUniValue; +}, + }; } -static UniValue mnauth(const JSONRPCRequest& request) +static RPCHelpMan mnauth() { - RPCHelpMan{"mnauth", + return RPCHelpMan{"mnauth", "\nOverride MNAUTH processing results for the specified node with a user provided data (-regtest only).\n", { {"nodeId", RPCArg::Type::NUM, RPCArg::Optional::NO, "Internal peer id of the node the mock data gets added to."}, @@ -576,7 +608,8 @@ static UniValue mnauth(const JSONRPCRequest& request) RPCResult::Type::BOOL, "result", "true, if the node was updated" }, RPCExamples{""}, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ if (!Params().MineBlocksOnDemand()) throw std::runtime_error("mnauth for regression testing (-regtest mode) only"); @@ -604,6 +637,8 @@ static UniValue mnauth(const JSONRPCRequest& request) }); return fSuccess; +}, + }; } static bool getAddressFromIndex(const AddressType& type, const uint160 &hash, std::string &address) @@ -673,9 +708,9 @@ static bool timestampSort(std::pair UniValue +{ std::vector > addresses; @@ -741,11 +777,13 @@ static UniValue getaddressmempool(const JSONRPCRequest& request) } return result; +}, + }; } -static UniValue getaddressutxos(const JSONRPCRequest& request) +static RPCHelpMan getaddressutxos() { - RPCHelpMan{"getaddressutxos", + return RPCHelpMan{"getaddressutxos", "\nReturns all unspent outputs for an address (requires addressindex to be enabled).\n", { {"addresses", RPCArg::Type::ARR, /* default */ "", "", @@ -771,7 +809,8 @@ static UniValue getaddressutxos(const JSONRPCRequest& request) HelpExampleCli("getaddressutxos", "'{\"addresses\": [\"" + EXAMPLE_ADDRESS[0] + "\"]}'") + HelpExampleRpc("getaddressutxos", "{\"addresses\": [\"" + EXAMPLE_ADDRESS[0] + "\"]}") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::vector > addresses; @@ -808,11 +847,13 @@ static UniValue getaddressutxos(const JSONRPCRequest& request) } return result; +}, + }; } -static UniValue getaddressdeltas(const JSONRPCRequest& request) +static RPCHelpMan getaddressdeltas() { - RPCHelpMan{"getaddressdeltas", + return RPCHelpMan{"getaddressdeltas", "\nReturns all changes for an address (requires addressindex to be enabled).\n", { {"addresses", RPCArg::Type::ARR, /* default */ "", "", @@ -838,7 +879,8 @@ static UniValue getaddressdeltas(const JSONRPCRequest& request) HelpExampleCli("getaddressdeltas", "'{\"addresses\": [\"" + EXAMPLE_ADDRESS[0] + "\"]}'") + HelpExampleRpc("getaddressdeltas", "{\"addresses\": [\"" + EXAMPLE_ADDRESS[0] + "\"]}") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ UniValue startValue = find_value(request.params[0].get_obj(), "start"); @@ -894,11 +936,13 @@ static UniValue getaddressdeltas(const JSONRPCRequest& request) } return result; +}, + }; } -static UniValue getaddressbalance(const JSONRPCRequest& request) +static RPCHelpMan getaddressbalance() { - RPCHelpMan{"getaddressbalance", + return RPCHelpMan{"getaddressbalance", "\nReturns the balance for an address(es) (requires addressindex to be enabled).\n", { {"addresses", RPCArg::Type::ARR, /* default */ "", "", @@ -919,7 +963,8 @@ static UniValue getaddressbalance(const JSONRPCRequest& request) HelpExampleCli("getaddressbalance", "'{\"addresses\": [\"" + EXAMPLE_ADDRESS[0] + "\"]}'") + HelpExampleRpc("getaddressbalance", "{\"addresses\": [\"" + EXAMPLE_ADDRESS[0] + "\"]}") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::vector > addresses; @@ -963,11 +1008,13 @@ static UniValue getaddressbalance(const JSONRPCRequest& request) return result; +}, + }; } -static UniValue getaddresstxids(const JSONRPCRequest& request) +static RPCHelpMan getaddresstxids() { - RPCHelpMan{"getaddresstxids", + return RPCHelpMan{"getaddresstxids", "\nReturns the txids for an address(es) (requires addressindex to be enabled).\n", { {"addresses", RPCArg::Type::ARR, /* default */ "", "", @@ -984,7 +1031,8 @@ static UniValue getaddresstxids(const JSONRPCRequest& request) HelpExampleCli("getaddresstxids", "'{\"addresses\": [\"" + EXAMPLE_ADDRESS[0] + "\"]}'") + HelpExampleRpc("getaddresstxids", "{\"addresses\": [\"" + EXAMPLE_ADDRESS[0] + "\"]}") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::vector > addresses; @@ -1041,11 +1089,13 @@ static UniValue getaddresstxids(const JSONRPCRequest& request) return result; +}, + }; } -static UniValue getspentinfo(const JSONRPCRequest& request) +static RPCHelpMan getspentinfo() { - RPCHelpMan{"getspentinfo", + return RPCHelpMan{"getspentinfo", "\nReturns the txid and index where an output is spent.\n", { {"request", RPCArg::Type::OBJ, /* default */ "", "", @@ -1065,7 +1115,8 @@ static UniValue getspentinfo(const JSONRPCRequest& request) HelpExampleCli("getspentinfo", "'{\"txid\": \"0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9\", \"index\": 0}'") + HelpExampleRpc("getspentinfo", "{\"txid\": \"0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9\", \"index\": 0}") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ UniValue txidValue = find_value(request.params[0].get_obj(), "txid"); UniValue indexValue = find_value(request.params[0].get_obj(), "index"); @@ -1091,19 +1142,21 @@ static UniValue getspentinfo(const JSONRPCRequest& request) obj.pushKV("height", value.m_block_height); return obj; +}, + }; } -static UniValue mockscheduler(const JSONRPCRequest& request) +static RPCHelpMan mockscheduler() { - RPCHelpMan{"mockscheduler", + return RPCHelpMan{"mockscheduler", "\nBump the scheduler into the future (-regtest only)\n", { {"delta_time", RPCArg::Type::NUM, RPCArg::Optional::NO, "Number of seconds to forward the scheduler into the future." }, }, RPCResults{}, RPCExamples{""}, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ if (!Params().IsMockableChain()) { throw std::runtime_error("mockscheduler is for regression testing (-regtest mode) only"); } @@ -1122,6 +1175,8 @@ static UniValue mockscheduler(const JSONRPCRequest& request) node_context->scheduler->MockForward(std::chrono::seconds(delta_seconds)); return NullUniValue; +}, + }; } static UniValue RPCLockedMemoryInfo() @@ -1156,12 +1211,12 @@ static std::string RPCMallocInfo() } #endif -static UniValue getmemoryinfo(const JSONRPCRequest& request) +static RPCHelpMan getmemoryinfo() { /* Please, avoid using the word "pool" here in the RPC interface or help, * as users will undoubtedly confuse it with the other "memory pool" */ - RPCHelpMan{"getmemoryinfo", + return RPCHelpMan{"getmemoryinfo", "Returns an object containing information about memory usage.\n", { {"mode", RPCArg::Type::STR, /* default */ "\"stats\"", "determines what kind of information is returned.\n" @@ -1191,7 +1246,8 @@ static UniValue getmemoryinfo(const JSONRPCRequest& request) HelpExampleCli("getmemoryinfo", "") + HelpExampleRpc("getmemoryinfo", "") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::string mode = request.params[0].isNull() ? "stats" : request.params[0].get_str(); if (mode == "stats") { @@ -1207,6 +1263,8 @@ static UniValue getmemoryinfo(const JSONRPCRequest& request) } else { throw JSONRPCError(RPC_INVALID_PARAMETER, "unknown mode " + mode); } +}, + }; } static void EnableOrDisableLogCategories(UniValue cats, bool enable) { @@ -1227,9 +1285,9 @@ static void EnableOrDisableLogCategories(UniValue cats, bool enable) { } } -static UniValue logging(const JSONRPCRequest& request) +static RPCHelpMan logging() { - RPCHelpMan{"logging", + return 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" @@ -1262,7 +1320,8 @@ static UniValue logging(const JSONRPCRequest& request) HelpExampleCli("logging", "\"[\\\"all\\\"]\" \"[\\\"http\\\"]\"") + HelpExampleRpc("logging", "[\"all\"], \"[libevent]\"") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ uint64_t original_log_categories = LogInstance().GetCategoryMask(); if (request.params[0].isArray()) { @@ -1294,25 +1353,41 @@ static UniValue logging(const JSONRPCRequest& request) } return result; +}, + }; } -static UniValue echo(const JSONRPCRequest& request) +static RPCHelpMan echo(const std::string& name) { - if (request.fHelp) - throw std::runtime_error( - RPCHelpMan{"echo|echojson ...", + return RPCHelpMan{name, "\nSimply echo back the input arguments. This command is for testing.\n" - "\nIt will return an internal bug report when exactly 100 arguments are passed.\n" + "\nIt will return an internal bug report when arg9='trigger_internal_bug' is passed.\n" "\nThe difference between echo and echojson is that echojson has argument conversion enabled in the client-side table in " "dash-cli and the GUI. There is no server-side difference.", - {}, + { + {"arg0", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""}, + {"arg1", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""}, + {"arg2", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""}, + {"arg3", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""}, + {"arg4", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""}, + {"arg5", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""}, + {"arg6", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""}, + {"arg7", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""}, + {"arg8", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""}, + {"arg9", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""}, + }, RPCResult{RPCResult::Type::NONE, "", "Returns whatever was passed in"}, RPCExamples{""}, - }.ToString() - ); - CHECK_NONFATAL(request.params.size() != 100); + [&](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"); + } return request.params; +}, + }; } static UniValue SummaryToJSON(const IndexSummary&& summary, std::string index_name) @@ -1373,12 +1448,15 @@ static RPCHelpMan getindexinfo() }; } +static RPCHelpMan echo() { return echo("echo"); } +static RPCHelpMan echojson() { return echo("echojson"); } + void RegisterMiscRPCCommands(CRPCTable &t) { static const CRPCCommand commands[] = { // category name actor (function) argNames // --------------------- ------------------------ ----------------------- ---------- - { "control", "debug", &debug, {} }, + { "control", "debug", &debug, {"category"} }, { "control", "getmemoryinfo", &getmemoryinfo, {"mode"} }, { "control", "logging", &logging, {"include", "exclude"}}, { "util", "validateaddress", &validateaddress, {"address"} }, @@ -1388,7 +1466,7 @@ static const CRPCCommand commands[] = { "util", "verifymessage", &verifymessage, {"address","signature","message"} }, { "util", "signmessagewithprivkey", &signmessagewithprivkey, {"privkey","message"} }, { "util", "getindexinfo", &getindexinfo, {"index_name"} }, - { "blockchain", "getspentinfo", &getspentinfo, {"json"} }, + { "blockchain", "getspentinfo", &getspentinfo, {"request"} }, /* Address index */ { "addressindex", "getaddressmempool", &getaddressmempool, {"addresses"} }, @@ -1398,7 +1476,7 @@ static const CRPCCommand commands[] = { "addressindex", "getaddressbalance", &getaddressbalance, {"addresses"} }, /* Dash features */ - { "dash", "mnsync", &mnsync, {} }, + { "dash", "mnsync", &mnsync, {"mode"} }, { "dash", "spork", &spork, {"command"} }, { "dash", "sporkupdate", &sporkupdate, {"name","value"} }, @@ -1406,12 +1484,11 @@ static const CRPCCommand commands[] = { "hidden", "setmocktime", &setmocktime, {"timestamp"}}, { "hidden", "mockscheduler", &mockscheduler, {"delta_time"}}, { "hidden", "echo", &echo, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}}, - { "hidden", "echojson", &echo, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}}, + { "hidden", "echojson", &echojson, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}}, { "hidden", "mnauth", &mnauth, {"nodeId", "proTxHash", "publicKey"}}, }; // clang-format on - - for (const auto& command : commands) { - t.appendCommand(command.name, &command); + for (const auto& c : commands) { + t.appendCommand(c.name, &c); } } diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 1a0710ec9323..6de82e6a7c44 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -39,9 +39,9 @@ const std::vector CONNECTION_TYPE_DOC{ "feeler (short-lived automatic connection for testing addresses)" }; -static UniValue getconnectioncount(const JSONRPCRequest& request) +static RPCHelpMan getconnectioncount() { - RPCHelpMan{"getconnectioncount", + return RPCHelpMan{"getconnectioncount", "\nReturns the number of connections to other nodes.\n", {}, RPCResult{ @@ -51,18 +51,20 @@ static UniValue getconnectioncount(const JSONRPCRequest& request) HelpExampleCli("getconnectioncount", "") + HelpExampleRpc("getconnectioncount", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ const NodeContext& node = EnsureAnyNodeContext(request.context); if(!node.connman) throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); return (int)node.connman->GetNodeCount(CConnman::CONNECTIONS_ALL); +}, + }; } -static UniValue ping(const JSONRPCRequest& request) +static RPCHelpMan ping() { - RPCHelpMan{"ping", + return 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", @@ -72,8 +74,8 @@ static UniValue ping(const JSONRPCRequest& request) HelpExampleCli("ping", "") + HelpExampleRpc("ping", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ const NodeContext& node = EnsureAnyNodeContext(request.context); if(!node.connman) throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); @@ -83,11 +85,13 @@ static UniValue ping(const JSONRPCRequest& request) pnode->fPingQueued = true; }); return NullUniValue; +}, + }; } -static UniValue getpeerinfo(const JSONRPCRequest& request) +static RPCHelpMan getpeerinfo() { - RPCHelpMan{"getpeerinfo", + return RPCHelpMan{"getpeerinfo", "\nReturns data about each connected network node as a json array of objects.\n", {}, RPCResult{ @@ -160,8 +164,8 @@ static UniValue getpeerinfo(const JSONRPCRequest& request) HelpExampleCli("getpeerinfo", "") + HelpExampleRpc("getpeerinfo", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ const NodeContext& node = EnsureAnyNodeContext(request.context); if(!node.connman || !node.peerman) { throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); @@ -259,14 +263,13 @@ static UniValue getpeerinfo(const JSONRPCRequest& request) } return ret; +}, + }; } -static UniValue addnode(const JSONRPCRequest& request) +static RPCHelpMan addnode() { - std::string strCommand; - if (!request.params[1].isNull()) - strCommand = request.params[1].get_str(); - RPCHelpMan{"addnode", + return 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" @@ -280,7 +283,11 @@ static UniValue addnode(const JSONRPCRequest& request) HelpExampleCli("addnode", "\"192.168.0.6:9999\" \"onetry\"") + HelpExampleRpc("addnode", "\"192.168.0.6:9999\", \"onetry\"") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ + std::string strCommand; + if (!request.params[1].isNull()) + strCommand = request.params[1].get_str(); const NodeContext& node = EnsureAnyNodeContext(request.context); if(!node.connman) @@ -307,11 +314,13 @@ static UniValue addnode(const JSONRPCRequest& request) } return NullUniValue; +}, + }; } -static UniValue disconnectnode(const JSONRPCRequest& request) +static RPCHelpMan disconnectnode() { - RPCHelpMan{"disconnectnode", + return 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", @@ -326,7 +335,8 @@ static UniValue disconnectnode(const JSONRPCRequest& request) + HelpExampleRpc("disconnectnode", "\"192.168.0.6:9999\"") + HelpExampleRpc("disconnectnode", "\"\", 1") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ const NodeContext& node = EnsureAnyNodeContext(request.context); if(!node.connman) @@ -352,11 +362,13 @@ static UniValue disconnectnode(const JSONRPCRequest& request) } return NullUniValue; +}, + }; } -static UniValue getaddednodeinfo(const JSONRPCRequest& request) +static RPCHelpMan getaddednodeinfo() { - RPCHelpMan{"getaddednodeinfo", + return RPCHelpMan{"getaddednodeinfo", "\nReturns information about the given added node, or all added nodes\n" "(note that onetry addnodes are not listed here)\n", { @@ -384,7 +396,8 @@ static UniValue getaddednodeinfo(const JSONRPCRequest& request) HelpExampleCli("getaddednodeinfo", "\"192.168.0.201\"") + HelpExampleRpc("getaddednodeinfo", "\"192.168.0.201\"") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ const NodeContext& node = EnsureAnyNodeContext(request.context); if(!node.connman) @@ -424,11 +437,13 @@ static UniValue getaddednodeinfo(const JSONRPCRequest& request) } return ret; +}, + }; } -static UniValue getnettotals(const JSONRPCRequest& request) +static RPCHelpMan getnettotals() { - RPCHelpMan{"getnettotals", + return RPCHelpMan{"getnettotals", "\nReturns information about network traffic, including bytes in, bytes out,\n" "and current time.\n", {}, @@ -453,7 +468,8 @@ static UniValue getnettotals(const JSONRPCRequest& request) HelpExampleCli("getnettotals", "") + HelpExampleRpc("getnettotals", "") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ const NodeContext& node = EnsureAnyNodeContext(request.context); if(!node.connman) throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); @@ -472,6 +488,8 @@ static UniValue getnettotals(const JSONRPCRequest& request) outboundLimit.pushKV("time_left_in_cycle", count_seconds(node.connman->GetMaxOutboundTimeLeftInCycle())); obj.pushKV("uploadtarget", outboundLimit); return obj; +}, + }; } static UniValue GetNetworksInfo() @@ -493,9 +511,9 @@ static UniValue GetNetworksInfo() return networks; } -static UniValue getnetworkinfo(const JSONRPCRequest& request) +static RPCHelpMan getnetworkinfo() { - RPCHelpMan{"getnetworkinfo", + return RPCHelpMan{"getnetworkinfo", "Returns an object containing various state info regarding P2P networking.\n", {}, RPCResult{ @@ -549,8 +567,8 @@ static UniValue getnetworkinfo(const JSONRPCRequest& request) HelpExampleCli("getnetworkinfo", "") + HelpExampleRpc("getnetworkinfo", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ LOCK(cs_main); UniValue obj(UniValue::VOBJ); obj.pushKV("version", CLIENT_VERSION); @@ -612,11 +630,13 @@ static UniValue getnetworkinfo(const JSONRPCRequest& request) obj.pushKV("localaddresses", localAddresses); obj.pushKV("warnings", GetWarnings(false).original); return obj; +}, + }; } -static UniValue setban(const JSONRPCRequest& request) +static RPCHelpMan setban() { - const RPCHelpMan help{"setban", + return RPCHelpMan{"setban", "\nAttempts to add or remove an IP/Subnet from the banned list.\n", { {"subnet", RPCArg::Type::STR, RPCArg::Optional::NO, "The IP/Subnet (see getpeerinfo for nodes IP) with an optional netmask (default is /32 = single IP)"}, @@ -630,7 +650,8 @@ static UniValue setban(const JSONRPCRequest& request) + HelpExampleCli("setban", "\"192.168.0.0/24\" \"add\"") + HelpExampleRpc("setban", "\"192.168.0.6\", \"add\", 86400") }, - }; + [&](const RPCHelpMan& help, const JSONRPCRequest& request) -> UniValue +{ std::string strCommand; if (!request.params[1].isNull()) strCommand = request.params[1].get_str(); @@ -693,11 +714,13 @@ static UniValue setban(const JSONRPCRequest& request) } } return NullUniValue; +}, + }; } -static UniValue listbanned(const JSONRPCRequest& request) +static RPCHelpMan listbanned() { - RPCHelpMan{"listbanned", + return RPCHelpMan{"listbanned", "\nList all manually banned IPs/Subnets.\n", {}, RPCResult{RPCResult::Type::ARR, "", "", @@ -713,7 +736,8 @@ static UniValue listbanned(const JSONRPCRequest& request) HelpExampleCli("listbanned", "") + HelpExampleRpc("listbanned", "") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ const NodeContext& node = EnsureAnyNodeContext(request.context); if(!node.banman) { @@ -736,11 +760,13 @@ static UniValue listbanned(const JSONRPCRequest& request) } return bannedAddresses; +}, + }; } -static UniValue clearbanned(const JSONRPCRequest& request) +static RPCHelpMan clearbanned() { - RPCHelpMan{"clearbanned", + return RPCHelpMan{"clearbanned", "\nClear all banned IPs.\n", {}, RPCResult{RPCResult::Type::NONE, "", ""}, @@ -748,7 +774,8 @@ static UniValue clearbanned(const JSONRPCRequest& request) HelpExampleCli("clearbanned", "") + HelpExampleRpc("clearbanned", "") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ const NodeContext& node = EnsureAnyNodeContext(request.context); if (!node.banman) { throw JSONRPCError(RPC_DATABASE_ERROR, "Error: Ban database not loaded"); @@ -757,11 +784,13 @@ static UniValue clearbanned(const JSONRPCRequest& request) node.banman->ClearBanned(); return NullUniValue; +}, + }; } -static UniValue cleardiscouraged(const JSONRPCRequest& request) +static RPCHelpMan cleardiscouraged() { - RPCHelpMan{"cleardiscouraged", + return RPCHelpMan{"cleardiscouraged", "\nClear all discouraged nodes.\n", {}, RPCResult{RPCResult::Type::NONE, "", ""}, @@ -769,7 +798,8 @@ static UniValue cleardiscouraged(const JSONRPCRequest& request) HelpExampleCli("cleardiscouraged", "") + HelpExampleRpc("cleardiscouraged", "") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ const NodeContext& node = EnsureAnyNodeContext(request.context); if (!node.banman) { throw JSONRPCError(RPC_DATABASE_ERROR, "Error: Ban database not loaded"); @@ -778,18 +808,21 @@ static UniValue cleardiscouraged(const JSONRPCRequest& request) node.banman->ClearDiscouraged(); return NullUniValue; +}, + }; } -static UniValue setnetworkactive(const JSONRPCRequest& request) +static RPCHelpMan setnetworkactive() { - RPCHelpMan{"setnetworkactive", + return RPCHelpMan{"setnetworkactive", "\nDisable/enable all p2p network activity.\n", { {"state", RPCArg::Type::BOOL, RPCArg::Optional::NO, "true to enable networking, false to disable"}, }, RPCResult{RPCResult::Type::BOOL, "", "The value that was passed in"}, RPCExamples{""}, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ const NodeContext& node = EnsureAnyNodeContext(request.context); if (!node.connman) { @@ -799,11 +832,13 @@ static UniValue setnetworkactive(const JSONRPCRequest& request) node.connman->SetNetworkActive(request.params[0].get_bool()); return node.connman->GetNetworkActive(); +}, + }; } -static UniValue getnodeaddresses(const JSONRPCRequest& request) +static RPCHelpMan getnodeaddresses() { - RPCHelpMan{"getnodeaddresses", + return RPCHelpMan{"getnodeaddresses", "\nReturn known addresses which can potentially be used to find new nodes in the network\n", { {"count", RPCArg::Type::NUM, /* default */ "1", "The maximum number of addresses to return. Specify 0 to return all known addresses."}, @@ -824,7 +859,8 @@ static UniValue getnodeaddresses(const JSONRPCRequest& request) HelpExampleCli("getnodeaddresses", "8") + HelpExampleRpc("getnodeaddresses", "8") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ const NodeContext& node = EnsureAnyNodeContext(request.context); if (!node.connman) { throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); @@ -850,11 +886,13 @@ static UniValue getnodeaddresses(const JSONRPCRequest& request) ret.push_back(obj); } return ret; +}, + }; } -static UniValue addpeeraddress(const JSONRPCRequest& request) +static RPCHelpMan addpeeraddress() { - RPCHelpMan{"addpeeraddress", + return RPCHelpMan{"addpeeraddress", "\nAdd the address of a potential peer to the address manager. This RPC is for testing only.\n", { {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The IP address of the peer"}, @@ -870,7 +908,8 @@ static UniValue addpeeraddress(const JSONRPCRequest& request) HelpExampleCli("addpeeraddress", "\"1.2.3.4\" 9999") + HelpExampleRpc("addpeeraddress", "\"1.2.3.4\", 9999") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ const NodeContext& node = EnsureAnyNodeContext(request.context); if (!node.addrman) { @@ -898,6 +937,8 @@ static UniValue addpeeraddress(const JSONRPCRequest& request) obj.pushKV("success", true); return obj; +}, + }; } void RegisterNetRPCCommands(CRPCTable &t) @@ -923,8 +964,7 @@ static const CRPCCommand commands[] = { "hidden", "addpeeraddress", &addpeeraddress, {"address", "port"} }, }; // clang-format on - - for (const auto& command : commands) { - t.appendCommand(command.name, &command); + for (const auto& c : commands) { + t.appendCommand(c.name, &c); } } diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index a36d8511d060..08f759ca98ff 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -112,9 +112,9 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, CTxMemPool& mempo entry.pushKV("chainlock", chainLock); } -static UniValue getrawtransaction(const JSONRPCRequest& request) +static RPCHelpMan getrawtransaction() { - RPCHelpMan{ + return RPCHelpMan{ "getrawtransaction", "\nReturn the raw transaction data.\n" @@ -198,8 +198,8 @@ static UniValue getrawtransaction(const JSONRPCRequest& request) + HelpExampleCli("getrawtransaction", "\"mytxid\" false \"myblockhash\"") + HelpExampleCli("getrawtransaction", "\"mytxid\" true \"myblockhash\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ const NodeContext& node = EnsureAnyNodeContext(request.context); ChainstateManager& chainman = EnsureChainman(node); @@ -264,10 +264,12 @@ static UniValue getrawtransaction(const JSONRPCRequest& request) if (blockindex) result.pushKV("in_active_chain", in_active_chain); TxToJSON(*tx, hash_block, mempool, chainman.ActiveChainstate(), *llmq_ctx.clhandler, *llmq_ctx.isman, result); return result; +}, + }; } -static UniValue getrawtransactionmulti(const JSONRPCRequest& request) { - RPCHelpMan{ +static RPCHelpMan getrawtransactionmulti() { + return RPCHelpMan{ "getrawtransactionmulti", "\nReturns the raw transaction data for multiple transactions.\n" "\nThis call is an extension of getrawtransaction that supports multiple transactions.\n" @@ -293,8 +295,8 @@ static UniValue getrawtransactionmulti(const JSONRPCRequest& request) { + HelpExampleRpc("getrawtransactionmulti", R"('{"blockhash1":["txid1","txid2"], "0":["txid3"]})") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ // Parse arguments UniValue transactions{request.params[0].get_obj()}; // Accept either a bool (true) or a num (>=1) to indicate verbose output. @@ -347,13 +349,14 @@ static UniValue getrawtransactionmulti(const JSONRPCRequest& request) { } } } - return result; +}, + }; } -static UniValue gettxchainlocks(const JSONRPCRequest& request) +static RPCHelpMan gettxchainlocks() { - RPCHelpMan{ + return RPCHelpMan{ "gettxchainlocks", "\nReturns the block height at which each transaction was mined, and indicates whether it is in the mempool, ChainLocked, or neither.\n", { @@ -378,8 +381,8 @@ static UniValue gettxchainlocks(const JSONRPCRequest& request) HelpExampleCli("gettxchainlocks", "'[\"mytxid\",...]'") + HelpExampleRpc("gettxchainlocks", "[\"mytxid\",...]") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ const NodeContext& node = EnsureAnyNodeContext(request.context); const LLMQContext& llmq_ctx = EnsureLLMQContext(node); const ChainstateManager& chainman = EnsureChainman(node); @@ -433,11 +436,13 @@ static UniValue gettxchainlocks(const JSONRPCRequest& request) result_arr.push_back(result); } return result_arr; +}, + }; } -static void getassetunlockstatuses_help(const JSONRPCRequest& request) +static RPCHelpMan getassetunlockstatuses() { - RPCHelpMan{ + return RPCHelpMan{ "getassetunlockstatuses", "\nReturns the status of given Asset Unlock indexes at the tip of the chain or at a specific block height if specified.\n", { @@ -462,13 +467,8 @@ static void getassetunlockstatuses_help(const JSONRPCRequest& request) HelpExampleCli("getassetunlockstatuses", "'[\"myindex\",...]'") + HelpExampleRpc("getassetunlockstatuses", "[\"myindex\",...]") }, - }.Check(request); -} - -static UniValue getassetunlockstatuses(const JSONRPCRequest& request) + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - getassetunlockstatuses_help(request); - const NodeContext& node = EnsureAnyNodeContext(request.context); const CTxMemPool& mempool = EnsureMemPool(node); const LLMQContext& llmq_ctx = EnsureLLMQContext(node); @@ -562,11 +562,13 @@ static UniValue getassetunlockstatuses(const JSONRPCRequest& request) } return result_arr; +}, + }; } -static UniValue gettxoutproof(const JSONRPCRequest& request) +static RPCHelpMan gettxoutproof() { - RPCHelpMan{"gettxoutproof", + return 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" @@ -588,8 +590,8 @@ static UniValue gettxoutproof(const JSONRPCRequest& request) + HelpExampleCli("gettxoutproof", "'[\"mytxid\",...]' \"blockhash\"") + HelpExampleRpc("gettxoutproof", "[\"mytxid\",...], \"blockhash\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::set setTxids; UniValue txids = request.params[0].get_array(); if (txids.empty()) { @@ -665,11 +667,13 @@ static UniValue gettxoutproof(const JSONRPCRequest& request) ssMB << mb; std::string strHex = HexStr(ssMB); return strHex; +}, + }; } -static UniValue verifytxoutproof(const JSONRPCRequest& request) +static RPCHelpMan verifytxoutproof() { - RPCHelpMan{"verifytxoutproof", + return 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", { @@ -685,8 +689,8 @@ static UniValue verifytxoutproof(const JSONRPCRequest& request) HelpExampleCli("verifytxoutproof", "\"proof\"") + HelpExampleRpc("gettxoutproof", "\"proof\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ CDataStream ssMB(ParseHexV(request.params[0], "proof"), SER_NETWORK, PROTOCOL_VERSION); CMerkleBlock merkleBlock; ssMB >> merkleBlock; @@ -714,11 +718,13 @@ static UniValue verifytxoutproof(const JSONRPCRequest& request) } return res; +}, + }; } -static UniValue createrawtransaction(const JSONRPCRequest& request) +static RPCHelpMan createrawtransaction() { - RPCHelpMan{"createrawtransaction", + return RPCHelpMan{"createrawtransaction", "\nCreate a transaction spending the given inputs and creating new outputs.\n" "Outputs can be addresses or data.\n" "Returns hex-encoded raw transaction.\n" @@ -764,8 +770,8 @@ static UniValue createrawtransaction(const JSONRPCRequest& request) + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"[{\\\"address\\\":0.01}]\"") + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"[{\\\"data\\\":\\\"00010203\\\"}]\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ RPCTypeCheck(request.params, { UniValue::VARR, UniValueType(), // ARR or OBJ, checked later @@ -776,11 +782,13 @@ static UniValue createrawtransaction(const JSONRPCRequest& request) CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2]); return EncodeHexTx(CTransaction(rawTx)); +}, + }; } -static UniValue decoderawtransaction(const JSONRPCRequest& request) +static RPCHelpMan decoderawtransaction() { - RPCHelpMan{"decoderawtransaction", + return RPCHelpMan{"decoderawtransaction", "\nReturn a JSON object representing the serialized, hex-encoded transaction.\n", { {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction hex string"}, @@ -834,8 +842,8 @@ static UniValue decoderawtransaction(const JSONRPCRequest& request) HelpExampleCli("decoderawtransaction", "\"hexstring\"") + HelpExampleRpc("decoderawtransaction", "\"hexstring\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ RPCTypeCheck(request.params, {UniValue::VSTR}); CMutableTransaction mtx; @@ -847,6 +855,8 @@ static UniValue decoderawtransaction(const JSONRPCRequest& request) TxToUniv(CTransaction(std::move(mtx)), uint256(), result, false); return result; +}, + }; } static std::string GetAllOutputTypes() @@ -859,9 +869,9 @@ static std::string GetAllOutputTypes() return Join(ret, ", "); } -static UniValue decodescript(const JSONRPCRequest& request) +static RPCHelpMan decodescript() { - RPCHelpMan{"decodescript", + return RPCHelpMan{"decodescript", "\nDecode a hex-encoded script.\n", { {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hex-encoded script"}, @@ -883,8 +893,8 @@ static UniValue decodescript(const JSONRPCRequest& request) HelpExampleCli("decodescript", "\"hexstring\"") + HelpExampleRpc("decodescript", "\"hexstring\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ RPCTypeCheck(request.params, {UniValue::VSTR}); UniValue r(UniValue::VOBJ); @@ -908,11 +918,13 @@ static UniValue decodescript(const JSONRPCRequest& request) } return r; +}, + }; } -static UniValue combinerawtransaction(const JSONRPCRequest& request) +static RPCHelpMan combinerawtransaction() { - RPCHelpMan{"combinerawtransaction", + return 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.", @@ -929,8 +941,8 @@ static UniValue combinerawtransaction(const JSONRPCRequest& request) RPCExamples{ HelpExampleCli("combinerawtransaction", R"('["myhex1", "myhex2", "myhex3"]')") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ UniValue txs = request.params[0].get_array(); std::vector txVariants(txs.size()); @@ -992,11 +1004,13 @@ static UniValue combinerawtransaction(const JSONRPCRequest& request) } return EncodeHexTx(CTransaction(mergedTx)); +}, + }; } -static UniValue signrawtransactionwithkey(const JSONRPCRequest& request) +static RPCHelpMan signrawtransactionwithkey() { - RPCHelpMan{"signrawtransactionwithkey", + return 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" @@ -1053,8 +1067,8 @@ static UniValue signrawtransactionwithkey(const JSONRPCRequest& request) HelpExampleCli("signrawtransactionwithkey", "\"myhex\" \"[\\\"key1\\\",\\\"key2\\\"]\"") + HelpExampleRpc("signrawtransactionwithkey", "\"myhex\", \"[\\\"key1\\\",\\\"key2\\\"]\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR, UniValue::VARR, UniValue::VSTR}, true); CMutableTransaction mtx; @@ -1087,11 +1101,13 @@ static UniValue signrawtransactionwithkey(const JSONRPCRequest& request) UniValue result(UniValue::VOBJ); SignTransaction(mtx, &keystore, coins, request.params[3], result); return result; +}, + }; } -UniValue sendrawtransaction(const JSONRPCRequest& request) +RPCHelpMan sendrawtransaction() { - RPCHelpMan{"sendrawtransaction", "\nSubmit a raw transaction (serialized, hex-encoded) to local node and network.\n" + return RPCHelpMan{"sendrawtransaction", "\nSubmit a raw transaction (serialized, hex-encoded) to local node and network.\n" "\nThe transaction will be sent unconditionally to all peers, so using sendrawtransaction\n" "for manual rebroadcast may degrade privacy by leaking the transaction's origin, as\n" "nodes will normally not rebroadcast non-wallet transactions already in their mempool.\n" @@ -1118,8 +1134,8 @@ UniValue sendrawtransaction(const JSONRPCRequest& request) "\nAs a JSON-RPC call\n" + HelpExampleRpc("sendrawtransaction", "\"signedhex\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ RPCTypeCheck(request.params, { UniValue::VSTR, UniValueType(), // VNUM or VSTR, checked inside AmountFromValue() @@ -1150,11 +1166,13 @@ UniValue sendrawtransaction(const JSONRPCRequest& request) } return tx->GetHash().GetHex(); +}, + }; } -static UniValue testmempoolaccept(const JSONRPCRequest& request) +static RPCHelpMan testmempoolaccept() { - RPCHelpMan{"testmempoolaccept", + return RPCHelpMan{"testmempoolaccept", "\nReturns result of mempool acceptance tests indicating if raw transaction (serialized, hex-encoded) would be accepted by mempool.\n" "\nIf multiple transactions are passed in, parents must come before children and package policies apply: the transactions cannot conflict with any mempool transactions or each other.\n" "\nIf one transaction fails, other transactions may not be fully validated (the 'allowed' key will be blank).\n" @@ -1200,8 +1218,8 @@ static UniValue testmempoolaccept(const JSONRPCRequest& request) "\nAs a JSON-RPC call\n" + HelpExampleRpc("testmempoolaccept", "[\"signedhex\"]") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ RPCTypeCheck(request.params, { UniValue::VARR, UniValueType(), // VNUM or VSTR, checked inside AmountFromValue() @@ -1286,11 +1304,13 @@ static UniValue testmempoolaccept(const JSONRPCRequest& request) rpc_result.push_back(result_inner); } return rpc_result; +}, + }; } -UniValue decodepsbt(const JSONRPCRequest& request) +static RPCHelpMan decodepsbt() { - RPCHelpMan{"decodepsbt", + return RPCHelpMan{"decodepsbt", "\nReturn a JSON object representing the serialized, base64-encoded partially signed Dash transaction.\n", { {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "The PSBT base64 string"}, @@ -1375,8 +1395,8 @@ UniValue decodepsbt(const JSONRPCRequest& request) RPCExamples{ HelpExampleCli("decodepsbt", "\"psbt\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ RPCTypeCheck(request.params, {UniValue::VSTR}); // Unserialize the transactions @@ -1537,11 +1557,13 @@ UniValue decodepsbt(const JSONRPCRequest& request) } return result; +}, + }; } -UniValue combinepsbt(const JSONRPCRequest& request) +static RPCHelpMan combinepsbt() { - RPCHelpMan{"combinepsbt", + return RPCHelpMan{"combinepsbt", "\nCombine multiple partially signed Dash transactions into one transaction.\n" "Implements the Combiner role.\n", { @@ -1557,8 +1579,8 @@ UniValue combinepsbt(const JSONRPCRequest& request) RPCExamples{ HelpExampleCli("combinepsbt", R"('["mybase64_1", "mybase64_2", "mybase64_3"]')") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ RPCTypeCheck(request.params, {UniValue::VARR}, true); // Unserialize the transactions @@ -1585,11 +1607,13 @@ UniValue combinepsbt(const JSONRPCRequest& request) CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); ssTx << merged_psbt; return EncodeBase64(ssTx); +}, + }; } -UniValue finalizepsbt(const JSONRPCRequest& request) +static RPCHelpMan finalizepsbt() { - RPCHelpMan{"finalizepsbt", + return 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_scriptSig field filled for inputs that are complete.\n" @@ -1610,8 +1634,8 @@ UniValue finalizepsbt(const JSONRPCRequest& request) RPCExamples{ HelpExampleCli("finalizepsbt", "\"psbt\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL}, true); // Unserialize the transactions @@ -1642,11 +1666,13 @@ UniValue finalizepsbt(const JSONRPCRequest& request) result.pushKV("complete", complete); return result; +}, + }; } -UniValue createpsbt(const JSONRPCRequest& request) +static RPCHelpMan createpsbt() { - RPCHelpMan{"createpsbt", + return RPCHelpMan{"createpsbt", "\nCreates a transaction in the Partially Signed Transaction format.\n" "Implements the Creator role.\n", { @@ -1686,8 +1712,8 @@ UniValue createpsbt(const JSONRPCRequest& request) RPCExamples{ HelpExampleCli("createpsbt", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ RPCTypeCheck(request.params, { UniValue::VARR, @@ -1713,11 +1739,13 @@ UniValue createpsbt(const JSONRPCRequest& request) ssTx << psbtx; return EncodeBase64(ssTx); +}, + }; } -UniValue converttopsbt(const JSONRPCRequest& request) +static RPCHelpMan converttopsbt() { - RPCHelpMan{"converttopsbt", + return 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", { @@ -1734,8 +1762,8 @@ UniValue converttopsbt(const JSONRPCRequest& request) "\nConvert the transaction to a PSBT\n" + HelpExampleCli("converttopsbt", "\"rawtransaction\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL, UniValue::VBOOL}, true); // parse hex string from parameter @@ -1768,12 +1796,13 @@ UniValue converttopsbt(const JSONRPCRequest& request) ssTx << psbtx; return EncodeBase64(ssTx); +}, + }; } -UniValue utxoupdatepsbt(const JSONRPCRequest& request) +static RPCHelpMan utxoupdatepsbt() { - - RPCHelpMan{"utxoupdatepsbt", + return RPCHelpMan{"utxoupdatepsbt", "\nUpdates a PSBT with data from output descriptors, UTXOs retrieved from the UTXO set or the mempool.\n", { {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"}, @@ -1790,7 +1819,9 @@ UniValue utxoupdatepsbt(const JSONRPCRequest& request) }, RPCExamples { HelpExampleCli("utxoupdatepsbt", "\"psbt\"") - }}.Check(request); + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR}, true); // Unserialize the transactions @@ -1852,11 +1883,13 @@ UniValue utxoupdatepsbt(const JSONRPCRequest& request) CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); ssTx << psbtx; return EncodeBase64(ssTx); +}, + }; } -UniValue joinpsbts(const JSONRPCRequest& request) +static RPCHelpMan joinpsbts() { - RPCHelpMan{"joinpsbts", + return RPCHelpMan{"joinpsbts", "\nJoins multiple distinct PSBTs with different inputs and outputs into one PSBT with inputs and outputs from all of the PSBTs\n" "No input in any of the PSBTs can be in more than one of the PSBTs.\n", { @@ -1870,8 +1903,9 @@ UniValue joinpsbts(const JSONRPCRequest& request) }, RPCExamples { HelpExampleCli("joinpsbts", "\"psbt\"") - }}.Check(request); - + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ RPCTypeCheck(request.params, {UniValue::VARR}, true); // Unserialize the transactions @@ -1923,11 +1957,13 @@ UniValue joinpsbts(const JSONRPCRequest& request) CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); ssTx << merged_psbt; return EncodeBase64(ssTx); +}, + }; } -UniValue analyzepsbt(const JSONRPCRequest& request) +static RPCHelpMan analyzepsbt() { - RPCHelpMan{"analyzepsbt", + return RPCHelpMan{"analyzepsbt", "\nAnalyzes and provides information about the current status of a PSBT and its inputs\n", { {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"} @@ -1965,8 +2001,9 @@ UniValue analyzepsbt(const JSONRPCRequest& request) }, RPCExamples { HelpExampleCli("analyzepsbt", "\"psbt\"") - }}.Check(request); - + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ RPCTypeCheck(request.params, {UniValue::VSTR}); // Unserialize the transaction @@ -2027,6 +2064,8 @@ UniValue analyzepsbt(const JSONRPCRequest& request) } return result; +}, + }; } void RegisterRawTransactionRPCCommands(CRPCTable &t) @@ -2037,7 +2076,7 @@ static const CRPCCommand commands[] = // --------------------- ------------------------ ----------------------- ---------- { "rawtransactions", "getassetunlockstatuses", &getassetunlockstatuses, {"indexes","height"} }, { "rawtransactions", "getrawtransaction", &getrawtransaction, {"txid","verbose","blockhash"} }, - { "rawtransactions", "getrawtransactionmulti", &getrawtransactionmulti, {"txid_map","verbose"} }, + { "rawtransactions", "getrawtransactionmulti", &getrawtransactionmulti, {"transactions","verbose"} }, { "rawtransactions", "gettxchainlocks", &gettxchainlocks, {"txids"} }, { "rawtransactions", "createrawtransaction", &createrawtransaction, {"inputs","outputs","locktime"} }, { "rawtransactions", "decoderawtransaction", &decoderawtransaction, {"hexstring"} }, @@ -2059,8 +2098,7 @@ static const CRPCCommand commands[] = { "blockchain", "verifytxoutproof", &verifytxoutproof, {"proof"} }, }; // clang-format on - - for (const auto& command : commands) { - t.appendCommand(command.name, &command); + for (const auto& c : commands) { + t.appendCommand(c.name, &c); } } diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 1376219bd6ae..c93e55126e42 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -286,23 +286,16 @@ static const CRPCCommand vRPCCommands[] = CRPCTable::CRPCTable() { - unsigned int vcidx; - for (vcidx = 0; vcidx < (sizeof(vRPCCommands) / sizeof(vRPCCommands[0])); vcidx++) - { - const CRPCCommand *pcmd; - - pcmd = &vRPCCommands[vcidx]; - mapCommands[pcmd->name].push_back(pcmd); + for (const auto& c : vRPCCommands) { + appendCommand(c.name, &c); } } -bool CRPCTable::appendCommand(const std::string& name, const CRPCCommand* pcmd) +void CRPCTable::appendCommand(const std::string& name, const CRPCCommand* pcmd) { - if (IsRPCRunning()) - return false; + CHECK_NONFATAL(!IsRPCRunning()); // Only add commands before rpc is running mapCommands[name].push_back(pcmd); - return true; } bool CRPCTable::removeCommand(const std::string& name, const CRPCCommand* pcmd) diff --git a/src/rpc/server.h b/src/rpc/server.h index afad34984585..d4a7ba60eb24 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -160,7 +160,7 @@ class CRPCTable /** * Appends a CRPCCommand to the dispatch table. * - * Returns false if RPC server is already running (dump concurrency protection). + * Precondition: RPC server is not running * * Commands with different method names but the same unique_id will * be considered aliases, and only the first registered method name will @@ -169,7 +169,7 @@ class CRPCTable * between calls based on method name, and aliased commands can also * register different names, types, and numbers of parameters. */ - bool appendCommand(const std::string& name, const CRPCCommand* pcmd); + void appendCommand(const std::string& name, const CRPCCommand* pcmd); bool removeCommand(const std::string& name, const CRPCCommand* pcmd); }; diff --git a/src/rpc/util.cpp b/src/rpc/util.cpp index ad0894954c0e..e850a17879f1 100644 --- a/src/rpc/util.cpp +++ b/src/rpc/util.cpp @@ -459,7 +459,7 @@ std::string RPCHelpMan::ToString() const ret += m_name; bool was_optional{false}; for (const auto& arg : m_args) { - if (arg.m_hidden) continue; + if (arg.m_hidden) break; // Any arg that follows is also hidden const bool optional = arg.IsOptional(); ret += " "; if (optional) { @@ -481,7 +481,7 @@ std::string RPCHelpMan::ToString() const Sections sections; for (size_t i{0}; i < m_args.size(); ++i) { const auto& arg = m_args.at(i); - if (arg.m_hidden) continue; + if (arg.m_hidden) break; // Any arg that follows is also hidden if (i == 0) ret += "\nArguments:\n"; diff --git a/src/rpc/util.h b/src/rpc/util.h index dcaf2bd701e0..768131795af9 100644 --- a/src/rpc/util.h +++ b/src/rpc/util.h @@ -354,6 +354,7 @@ class RPCHelpMan } } + // TODO: drop it, that's dash specific workaround [[ noreturn ]] inline void Throw() const { throw std::runtime_error(ToString()); } diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index dfb1ec1139d8..9ca319641b5f 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -68,9 +68,9 @@ static void RescanWallet(CWallet& wallet, const WalletRescanReserver& reserver, } } -UniValue importprivkey(const JSONRPCRequest& request) +RPCHelpMan importprivkey() { - RPCHelpMan{"importprivkey", + return RPCHelpMan{"importprivkey", "\nAdds a private key (as returned by dumpprivkey) to your wallet. Requires a new wallet backup.\n" "Hint: use importmulti to import more than one private key.\n" "\nNote: This call can take over an hour to complete if rescan is true, during that time, other rpc calls\n" @@ -93,8 +93,8 @@ UniValue importprivkey(const JSONRPCRequest& request) "\nAs a JSON-RPC call\n" + HelpExampleRpc("importprivkey", "\"mykey\", \"testing\", false") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -156,11 +156,13 @@ UniValue importprivkey(const JSONRPCRequest& request) RescanWallet(*pwallet, reserver); } return NullUniValue; +}, + }; } -UniValue abortrescan(const JSONRPCRequest& request) +RPCHelpMan abortrescan() { - RPCHelpMan{"abortrescan", + return RPCHelpMan{"abortrescan", "\nStops current wallet rescan triggered by an RPC call, e.g. by an importprivkey call.\n", {}, RPCResult{RPCResult::Type::BOOL, "", "Whether the abort was successful"}, @@ -172,20 +174,22 @@ UniValue abortrescan(const JSONRPCRequest& request) "\nAs a JSON-RPC call\n" + HelpExampleRpc("abortrescan", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); if (!pwallet->IsScanning() || pwallet->IsAbortingRescan()) return false; - pwallet->AbortRescan(); - return true; - } + pwallet->AbortRescan(); + return true; +}, + }; +} -UniValue importaddress(const JSONRPCRequest& request) +RPCHelpMan importaddress() { - RPCHelpMan{"importaddress", + return 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" "\nNote: This call can take over an hour to complete if rescan is true, during that time, other rpc calls\n" "may report that the imported address exists but related transactions are still missing, leading to temporarily incorrect/bogus balances and unspent outputs until rescan completes.\n" @@ -208,8 +212,8 @@ UniValue importaddress(const JSONRPCRequest& request) "\nAs a JSON-RPC call\n" + HelpExampleRpc("importaddress", "\"myaddress\", \"testing\", false") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -279,11 +283,13 @@ UniValue importaddress(const JSONRPCRequest& request) } return NullUniValue; +}, + }; } -UniValue importprunedfunds(const JSONRPCRequest& request) +RPCHelpMan importprunedfunds() { - RPCHelpMan{"importprunedfunds", + return 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, RPCArg::Optional::NO, "A raw transaction in hex funding an already-existing address in wallet"}, @@ -291,8 +297,8 @@ UniValue importprunedfunds(const JSONRPCRequest& request) }, RPCResult{RPCResult::Type::NONE, "", ""}, RPCExamples{""}, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -336,11 +342,13 @@ UniValue importprunedfunds(const JSONRPCRequest& request) } throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No addresses in wallet correspond to included transaction"); +}, + }; } -UniValue removeprunedfunds(const JSONRPCRequest& request) +RPCHelpMan removeprunedfunds() { - RPCHelpMan{"removeprunedfunds", + return 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, RPCArg::Optional::NO, "The hex-encoded id of the transaction you are deleting"}, @@ -351,8 +359,8 @@ UniValue removeprunedfunds(const JSONRPCRequest& request) "\nAs a JSON-RPC call\n" + HelpExampleRpc("removeprunedfunds", "\"a8d0c0184dde994a09ec054286f1ce581bebf46446a512166eae7628734ea0a5\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -373,11 +381,13 @@ UniValue removeprunedfunds(const JSONRPCRequest& request) } return NullUniValue; +}, + }; } -UniValue importpubkey(const JSONRPCRequest& request) +RPCHelpMan importpubkey() { - RPCHelpMan{"importpubkey", + return 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" "Hint: use importmulti to import more than one public key.\n" "\nNote: This call can take over an hour to complete if rescan is true, during that time, other rpc calls\n" @@ -396,8 +406,8 @@ UniValue importpubkey(const JSONRPCRequest& request) "\nAs a JSON-RPC call\n" + HelpExampleRpc("importpubkey", "\"mypubkey\", \"testing\", false") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -453,12 +463,14 @@ UniValue importpubkey(const JSONRPCRequest& request) } return NullUniValue; +}, + }; } -UniValue importwallet(const JSONRPCRequest& request) +RPCHelpMan importwallet() { - RPCHelpMan{"importwallet", + return RPCHelpMan{"importwallet", "\nImports keys from a wallet dump file (see dumpwallet). Requires a new wallet backup to include imported keys.\n" "Note: Use \"getwalletinfo\" to query the scanning progress.\n", { @@ -473,8 +485,8 @@ UniValue importwallet(const JSONRPCRequest& request) "\nImport using the json rpc call\n" + HelpExampleRpc("importwallet", "\"test\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -613,11 +625,13 @@ UniValue importwallet(const JSONRPCRequest& request) throw JSONRPCError(RPC_WALLET_ERROR, "Error adding some keys/scripts to wallet"); return NullUniValue; +}, + }; } -UniValue importelectrumwallet(const JSONRPCRequest& request) +RPCHelpMan importelectrumwallet() { - RPCHelpMan{"importelectrumwallet", + return RPCHelpMan{"importelectrumwallet", "\nImports keys from an Electrum wallet export file (.csv or .json)\n", { {"filename", RPCArg::Type::STR, RPCArg::Optional::NO, "The Electrum wallet export file, should be in csv or json format"}, @@ -632,7 +646,8 @@ UniValue importelectrumwallet(const JSONRPCRequest& request) + HelpExampleRpc("importelectrumwallet", "\"test.csv\"") + HelpExampleRpc("importelectrumwallet", "\"test.json\"") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; @@ -790,11 +805,13 @@ UniValue importelectrumwallet(const JSONRPCRequest& request) throw JSONRPCError(RPC_WALLET_ERROR, "Error adding some keys to wallet"); return NullUniValue; +}, + }; } -UniValue dumpprivkey(const JSONRPCRequest& request) +RPCHelpMan dumpprivkey() { - RPCHelpMan{"dumpprivkey", + return RPCHelpMan{"dumpprivkey", "\nReveals the private key corresponding to 'address'.\n" "Then the importprivkey can be used with this output\n", { @@ -808,8 +825,8 @@ UniValue dumpprivkey(const JSONRPCRequest& request) + HelpExampleCli("importprivkey", "\"mykey\"") + HelpExampleRpc("dumpprivkey", "\"myaddress\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; const CWallet* const pwallet = wallet.get(); @@ -834,11 +851,13 @@ UniValue dumpprivkey(const JSONRPCRequest& request) throw JSONRPCError(RPC_WALLET_ERROR, "Private key for address " + strAddress + " is not known"); } return EncodeSecret(vchSecret); +}, + }; } -UniValue dumphdinfo(const JSONRPCRequest& request) +RPCHelpMan dumphdinfo() { - RPCHelpMan{"dumphdinfo", + return RPCHelpMan{"dumphdinfo", "Returns an object containing sensitive private info about this HD wallet.\n", {}, RPCResult{ @@ -853,8 +872,8 @@ UniValue dumphdinfo(const JSONRPCRequest& request) HelpExampleCli("dumphdinfo", "") + HelpExampleRpc("dumphdinfo", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; const CWallet* const pwallet = wallet.get(); @@ -881,11 +900,13 @@ UniValue dumphdinfo(const JSONRPCRequest& request) obj.pushKV("mnemonicpassphrase", ssMnemonicPassphrase.c_str()); return obj; +}, + }; } -UniValue dumpwallet(const JSONRPCRequest& request) +RPCHelpMan dumpwallet() { - RPCHelpMan{"dumpwallet", + return 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 dumpfile too, their corresponding addresses will 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" @@ -905,8 +926,8 @@ UniValue dumpwallet(const JSONRPCRequest& request) HelpExampleCli("dumpwallet", "\"test\"") + HelpExampleRpc("dumpwallet", "\"test\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr const pwallet = GetWalletForJSONRPCRequest(request); if (!pwallet) return NullUniValue; @@ -1056,6 +1077,8 @@ UniValue dumpwallet(const JSONRPCRequest& request) obj.pushKV("warning", strWarning); return obj; +}, + }; } struct ImportData @@ -1430,9 +1453,9 @@ static int64_t GetImportTimestamp(const UniValue& data, int64_t now) throw JSONRPCError(RPC_TYPE_ERROR, "Missing required timestamp field for key"); } -UniValue importmulti(const JSONRPCRequest& mainRequest) +RPCHelpMan importmulti() { - RPCHelpMan{"importmulti", + return RPCHelpMan{"importmulti", "\nImport addresses/scripts (with private or public keys, redeem script (P2SH)), optionally rescanning the blockchain from the earliest creation time of the imported scripts. Requires a new wallet backup.\n" "If an address/script is imported without all of the private keys required to spend from that address, it will be watchonly. The 'watchonly' option must be set to true in this case or a warning will be returned.\n" "Conversely, if all the private keys are provided and the address/script is spendable, the watchonly option must be set to false, or a warning will be returned.\n" @@ -1504,7 +1527,8 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) "{ \"scriptPubKey\": { \"address\": \"\" }, \"label\": \"example 2\", \"timestamp\": 1455191480 }]'") + HelpExampleCli("importmulti", "'[{ \"scriptPubKey\": { \"address\": \"\" }, \"timestamp\":1455191478 }]' '{ \"rescan\": false}'") }, - }.Check(mainRequest); + [&](const RPCHelpMan& self, const JSONRPCRequest& mainRequest) -> UniValue +{ RPCTypeCheck(mainRequest.params, {UniValue::VARR, UniValue::VOBJ}); @@ -1614,6 +1638,8 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) } return response; +}, + }; } static UniValue ProcessDescriptorImport(CWallet * const pwallet, const UniValue& data, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) @@ -1757,8 +1783,8 @@ static UniValue ProcessDescriptorImport(CWallet * const pwallet, const UniValue& return result; } -UniValue importdescriptors(const JSONRPCRequest& main_request) { - RPCHelpMan{"importdescriptors", +RPCHelpMan importdescriptors() { + return RPCHelpMan{"importdescriptors", "\nImport descriptors. This will trigger a rescan of the blockchain based on the earliest timestamp of all descriptors being imported. Requires a new wallet backup.\n" "\nNote: This call can take over an hour to complete if using an early timestamp; during that time, other rpc calls\n" "may report that the imported keys, addresses or scripts exist but related transactions are still missing.\n", @@ -1807,8 +1833,8 @@ UniValue importdescriptors(const JSONRPCRequest& main_request) { "{ \"desc\": \"\", \"label\": \"example 2\", \"timestamp\": 1455191480 }]'") + HelpExampleCli("importdescriptors", "'[{ \"desc\": \"\", \"timestamp\":1455191478, \"active\": true, \"range\": [0,100], \"label\": \"\" }]'") }, - }.Check(main_request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& main_request) -> UniValue +{ // Acquire the wallet std::shared_ptr const wallet = GetWalletForJSONRPCRequest(main_request); if (!wallet) return NullUniValue; @@ -1907,6 +1933,8 @@ UniValue importdescriptors(const JSONRPCRequest& main_request) { } return response; +}, + }; } RPCHelpMan listdescriptors() diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index a7a52ea0a072..fd134fc7894f 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -236,9 +236,9 @@ static void SetFeeEstimateMode(const CWallet* pwallet, CCoinControl& cc, const U } } -UniValue getnewaddress(const JSONRPCRequest& request) +RPCHelpMan getnewaddress() { - RPCHelpMan{"getnewaddress", + return RPCHelpMan{"getnewaddress", "\nReturns a new Dash address for receiving payments.\n" "If 'label' is specified, it is added to the address book \n" "so payments received with the address will be associated with 'label'.\n", @@ -252,8 +252,8 @@ UniValue getnewaddress(const JSONRPCRequest& request) HelpExampleCli("getnewaddress", "") + HelpExampleRpc("getnewaddress", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -275,11 +275,13 @@ UniValue getnewaddress(const JSONRPCRequest& request) throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, error); } return EncodeDestination(dest); +}, + }; } -UniValue getrawchangeaddress(const JSONRPCRequest& request) +RPCHelpMan getrawchangeaddress() { - RPCHelpMan{"getrawchangeaddress", + return RPCHelpMan{"getrawchangeaddress", "\nReturns a new Dash address, for receiving change.\n" "This is for use with raw transactions, NOT normal use.\n", {}, @@ -290,8 +292,8 @@ UniValue getrawchangeaddress(const JSONRPCRequest& request) HelpExampleCli("getrawchangeaddress", "") + HelpExampleRpc("getrawchangeaddress", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -308,12 +310,14 @@ UniValue getrawchangeaddress(const JSONRPCRequest& request) throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, error); } return EncodeDestination(dest); +}, + }; } -static UniValue setlabel(const JSONRPCRequest& request) +static RPCHelpMan setlabel() { - RPCHelpMan{"setlabel", + return RPCHelpMan{"setlabel", "\nSets the label associated with the given address.\n", { {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The Dash address to be associated with a label."}, @@ -324,8 +328,8 @@ static UniValue setlabel(const JSONRPCRequest& request) HelpExampleCli("setlabel", "\"" + EXAMPLE_ADDRESS[0] + "\" \"tabby\"") + HelpExampleRpc("setlabel", "\"" + EXAMPLE_ADDRESS[0] + "\", \"tabby\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -346,6 +350,8 @@ static UniValue setlabel(const JSONRPCRequest& request) } return NullUniValue; +}, + }; } @@ -384,13 +390,9 @@ static CTransactionRef SendMoney(CWallet* const pwallet, const CTxDestination& a return tx; } -static UniValue sendtoaddress(const JSONRPCRequest& request) +static RPCHelpMan sendtoaddress() { - std::shared_ptr const wallet = GetWalletForJSONRPCRequest(request); - if (!wallet) return NullUniValue; - CWallet* const pwallet = wallet.get(); - - RPCHelpMan{"sendtoaddress", + return RPCHelpMan{"sendtoaddress", "\nSend an amount to a given address." + HELP_REQUIRING_PASSPHRASE, { @@ -422,7 +424,11 @@ static UniValue sendtoaddress(const JSONRPCRequest& request) + HelpExampleCli("sendtoaddress", "\"" + EXAMPLE_ADDRESS[0] + "\" 0.1 \"\" \"\" false true 2 " + (CURRENCY_ATOM + "/B")) + HelpExampleRpc("sendtoaddress", "\"" + EXAMPLE_ADDRESS[0] + "\", 0.1, \"donation\", \"seans outpost\"") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ + std::shared_ptr const wallet = GetWalletForJSONRPCRequest(request); + if (!wallet) return NullUniValue; + CWallet* const pwallet = wallet.get(); // Make sure the results are valid at least up to the most recent block // the user could have gotten from another RPC command prior to now @@ -469,21 +475,31 @@ static UniValue sendtoaddress(const JSONRPCRequest& request) CTransactionRef tx = SendMoney(pwallet, dest, nAmount, fSubtractFeeFromAmount, coin_control, std::move(mapValue)); return tx->GetHash().GetHex(); +}, + }; } // DEPRECATED -static UniValue instantsendtoaddress(const JSONRPCRequest& request) +static RPCHelpMan instantsendtoaddress() +{ + return RPCHelpMan{"instantsendtoaddress", + "instantsendtoaddress is deprecated and sendtoaddress should be used instead", + {}, + RPCResult{ + RPCResult::Type::STR_HEX, "txid", "The transaction id." + }, + RPCExamples{""}, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - if (request.fHelp) { - throw std::runtime_error("instantsendtoaddress is deprecated and sendtoaddress should be used instead"); - } LogPrintf("WARNING: Used deprecated RPC method 'instantsendtoaddress'! Please use 'sendtoaddress' instead\n"); - return sendtoaddress(request); + return sendtoaddress().HandleRequest(request); +}, + }; } -static UniValue listaddressgroupings(const JSONRPCRequest& request) +static RPCHelpMan listaddressgroupings() { - RPCHelpMan{"listaddressgroupings", + return RPCHelpMan{"listaddressgroupings", "\nLists groups of addresses which have had their common ownership\n" "made public by common use as inputs or as the resulting change\n" "in past transactions\n", @@ -505,8 +521,8 @@ static UniValue listaddressgroupings(const JSONRPCRequest& request) HelpExampleCli("listaddressgroupings", "") + HelpExampleRpc("listaddressgroupings", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; const CWallet* const pwallet = wallet.get(); @@ -537,11 +553,13 @@ static UniValue listaddressgroupings(const JSONRPCRequest& request) jsonGroupings.push_back(jsonGrouping); } return jsonGroupings; +}, + }; } -static UniValue listaddressbalances(const JSONRPCRequest& request) +static RPCHelpMan listaddressbalances() { - RPCHelpMan{"listaddressbalances", + return RPCHelpMan{"listaddressbalances", "\nLists addresses of this wallet and their balances\n", { {"minamount", RPCArg::Type::NUM, /* default */ "0", "Minimum balance in " + CURRENCY_UNIT + " an address should have to be shown in the list"}, @@ -557,9 +575,9 @@ static UniValue listaddressbalances(const JSONRPCRequest& request) + HelpExampleCli("listaddressbalances", "10") + HelpExampleRpc("listaddressbalances", "") + HelpExampleRpc("listaddressbalances", "10") - } - }.Check(request); - + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; const CWallet* const pwallet = wallet.get(); @@ -580,11 +598,13 @@ static UniValue listaddressbalances(const JSONRPCRequest& request) jsonBalances.pushKV(EncodeDestination(balance.first), ValueFromAmount(balance.second)); return jsonBalances; +}, + }; } -static UniValue signmessage(const JSONRPCRequest& request) +static RPCHelpMan signmessage() { - RPCHelpMan{"signmessage", + return RPCHelpMan{"signmessage", "\nSign a message with the private key of an address" + HELP_REQUIRING_PASSPHRASE, { @@ -604,8 +624,8 @@ static UniValue signmessage(const JSONRPCRequest& request) "\nAs a JSON-RPC call\n" + HelpExampleRpc("signmessage", "\"" + EXAMPLE_ADDRESS[0] + "\", \"my message\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -636,6 +656,8 @@ static UniValue signmessage(const JSONRPCRequest& request) } return signature; +}, + }; } static CAmount GetReceived(const CWallet& wallet, const UniValue& params, bool by_label) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet) @@ -686,9 +708,9 @@ static CAmount GetReceived(const CWallet& wallet, const UniValue& params, bool b } -static UniValue getreceivedbyaddress(const JSONRPCRequest& request) +static RPCHelpMan getreceivedbyaddress() { - RPCHelpMan{"getreceivedbyaddress", + return RPCHelpMan{"getreceivedbyaddress", "\nReturns the total amount received by the given address in transactions with at least minconf confirmations.\n", { {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The Dash address for transactions."}, @@ -708,8 +730,8 @@ static UniValue getreceivedbyaddress(const JSONRPCRequest& request) "\nAs a JSON-RPC call\n" + HelpExampleRpc("getreceivedbyaddress", "\"" + EXAMPLE_ADDRESS[0] + "\", 6") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; const CWallet* const pwallet = wallet.get(); @@ -721,12 +743,14 @@ static UniValue getreceivedbyaddress(const JSONRPCRequest& request) LOCK(pwallet->cs_wallet); return ValueFromAmount(GetReceived(*pwallet, request.params, /* by_label */ false)); +}, + }; } -static UniValue getreceivedbylabel(const JSONRPCRequest& request) +static RPCHelpMan getreceivedbylabel() { - RPCHelpMan{"getreceivedbylabel", + return RPCHelpMan{"getreceivedbylabel", "\nReturns the total amount received by addresses with