diff options
Diffstat (limited to 'src/rpc/blockchain.cpp')
-rw-r--r-- | src/rpc/blockchain.cpp | 366 |
1 files changed, 212 insertions, 154 deletions
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 92f6f0fe11..ec87f42c93 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -12,8 +12,8 @@ #include <checkpoints.h> #include <coins.h> #include <consensus/validation.h> -#include <validation.h> #include <core_io.h> +#include <hash.h> #include <index/txindex.h> #include <key_io.h> #include <policy/feerate.h> @@ -21,14 +21,15 @@ #include <policy/rbf.h> #include <primitives/transaction.h> #include <rpc/server.h> +#include <rpc/util.h> #include <script/descriptor.h> #include <streams.h> #include <sync.h> #include <txdb.h> #include <txmempool.h> -#include <util/system.h> #include <util/strencodings.h> -#include <hash.h> +#include <util/system.h> +#include <validation.h> #include <validationinterface.h> #include <versionbitsinfo.h> #include <warnings.h> @@ -38,7 +39,6 @@ #include <univalue.h> -#include <boost/algorithm/string.hpp> #include <boost/thread/thread.hpp> // boost::thread::interrupt #include <memory> @@ -162,8 +162,9 @@ static UniValue getblockcount(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 0) throw std::runtime_error( - "getblockcount\n" - "\nReturns the number of blocks in the longest blockchain.\n" + RPCHelpMan{"getblockcount", + "\nReturns the number of blocks in the longest blockchain.\n", {}} + .ToString() + "\nResult:\n" "n (numeric) The current block count\n" "\nExamples:\n" @@ -179,8 +180,9 @@ static UniValue getbestblockhash(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 0) throw std::runtime_error( - "getbestblockhash\n" - "\nReturns the hash of the best (tip) block in the longest blockchain.\n" + RPCHelpMan{"getbestblockhash", + "\nReturns the hash of the best (tip) block in the longest blockchain.\n", {}} + .ToString() + "\nResult:\n" "\"hex\" (string) the block hash, hex-encoded\n" "\nExamples:\n" @@ -206,11 +208,13 @@ static UniValue waitfornewblock(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() > 1) throw std::runtime_error( - "waitfornewblock (timeout)\n" - "\nWaits for a specific new block and returns useful info about it.\n" - "\nReturns the current block on timeout or exit.\n" - "\nArguments:\n" - "1. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n" + RPCHelpMan{"waitfornewblock", + "\nWaits for a specific new block and returns useful info about it.\n" + "\nReturns the current block on timeout or exit.\n", + { + {"timeout", RPCArg::Type::NUM, /* opt */ true, /* default_val */ "0", "Time in milliseconds to wait for a response. 0 indicates no timeout."}, + }} + .ToString() + "\nResult:\n" "{ (json object)\n" " \"hash\" : { (string) The blockhash\n" @@ -244,12 +248,14 @@ static UniValue waitforblock(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw std::runtime_error( - "waitforblock <blockhash> (timeout)\n" - "\nWaits for a specific new block and returns useful info about it.\n" - "\nReturns the current block on timeout or exit.\n" - "\nArguments:\n" - "1. \"blockhash\" (required, string) Block hash to wait for.\n" - "2. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n" + RPCHelpMan{"waitforblock", + "\nWaits for a specific new block and returns useful info about it.\n" + "\nReturns the current block on timeout or exit.\n", + { + {"blockhash", RPCArg::Type::STR_HEX, /* opt */ false, /* default_val */ "", "Block hash to wait for."}, + {"timeout", RPCArg::Type::NUM, /* opt */ true, /* default_val */ "0", "Time in milliseconds to wait for a response. 0 indicates no timeout."}, + }} + .ToString() + "\nResult:\n" "{ (json object)\n" " \"hash\" : { (string) The blockhash\n" @@ -286,13 +292,15 @@ static UniValue waitforblockheight(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw std::runtime_error( - "waitforblockheight <height> (timeout)\n" - "\nWaits for (at least) block height and returns the height and hash\n" - "of the current tip.\n" - "\nReturns the current block on timeout or exit.\n" - "\nArguments:\n" - "1. height (required, int) Block height to wait for (int)\n" - "2. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n" + 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", + { + {"height", RPCArg::Type::NUM, /* opt */ false, /* default_val */ "", "Block height to wait for."}, + {"timeout", RPCArg::Type::NUM, /* opt */ true, /* default_val */ "0", "Time in milliseconds to wait for a response. 0 indicates no timeout."}, + }} + .ToString() + "\nResult:\n" "{ (json object)\n" " \"hash\" : { (string) The blockhash\n" @@ -328,8 +336,9 @@ static UniValue syncwithvalidationinterfacequeue(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() > 0) { throw std::runtime_error( - "syncwithvalidationinterfacequeue\n" - "\nWaits for the validation interface queue to catch up on everything that was there when we entered this function.\n" + RPCHelpMan{"syncwithvalidationinterfacequeue", + "\nWaits for the validation interface queue to catch up on everything that was there when we entered this function.\n", {}} + .ToString() + "\nExamples:\n" + HelpExampleCli("syncwithvalidationinterfacequeue","") + HelpExampleRpc("syncwithvalidationinterfacequeue","") @@ -343,8 +352,9 @@ static UniValue getdifficulty(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 0) throw std::runtime_error( - "getdifficulty\n" - "\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n" + RPCHelpMan{"getdifficulty", + "\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n", {}} + .ToString() + "\nResult:\n" "n.nnn (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty.\n" "\nExamples:\n" @@ -477,11 +487,13 @@ static UniValue getrawmempool(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() > 1) throw std::runtime_error( - "getrawmempool ( verbose )\n" - "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n" - "\nHint: use getmempoolentry to fetch a specific transaction from the mempool.\n" - "\nArguments:\n" - "1. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n" + 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", + { + {"verbose", RPCArg::Type::BOOL, /* opt */ true, /* default_val */ "false", "True for a json object, false for array of transaction ids"}, + }} + .ToString() + "\nResult: (for verbose = false):\n" "[ (json array of string)\n" " \"transactionid\" (string) The transaction id\n" @@ -509,11 +521,13 @@ static UniValue getmempoolancestors(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { throw std::runtime_error( - "getmempoolancestors txid ( verbose )\n" - "\nIf txid is in the mempool, returns all in-mempool ancestors.\n" - "\nArguments:\n" - "1. \"txid\" (string, required) The transaction id (must be in mempool)\n" - "2. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n" + RPCHelpMan{"getmempoolancestors", + "\nIf txid is in the mempool, returns all in-mempool ancestors.\n", + { + {"txid", RPCArg::Type::STR_HEX, /* opt */ false, /* default_val */ "", "The transaction id (must be in mempool)"}, + {"verbose", RPCArg::Type::BOOL, /* opt */ true, /* default_val */ "false", "True for a json object, false for array of transaction ids"}, + }} + .ToString() + "\nResult (for verbose = false):\n" "[ (json array of strings)\n" " \"transactionid\" (string) The transaction id of an in-mempool ancestor transaction\n" @@ -573,11 +587,13 @@ static UniValue getmempooldescendants(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { throw std::runtime_error( - "getmempooldescendants txid ( verbose )\n" - "\nIf txid is in the mempool, returns all in-mempool descendants.\n" - "\nArguments:\n" - "1. \"txid\" (string, required) The transaction id (must be in mempool)\n" - "2. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n" + RPCHelpMan{"getmempooldescendants", + "\nIf txid is in the mempool, returns all in-mempool descendants.\n", + { + {"txid", RPCArg::Type::STR_HEX, /* opt */ false, /* default_val */ "", "The transaction id (must be in mempool)"}, + {"verbose", RPCArg::Type::BOOL, /* opt */ true, /* default_val */ "false", "True for a json object, false for array of transaction ids"}, + }} + .ToString() + "\nResult (for verbose = false):\n" "[ (json array of strings)\n" " \"transactionid\" (string) The transaction id of an in-mempool descendant transaction\n" @@ -637,10 +653,12 @@ static UniValue getmempoolentry(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 1) { throw std::runtime_error( - "getmempoolentry txid\n" - "\nReturns mempool data for given transaction\n" - "\nArguments:\n" - "1. \"txid\" (string, required) The transaction id (must be in mempool)\n" + RPCHelpMan{"getmempoolentry", + "\nReturns mempool data for given transaction\n", + { + {"txid", RPCArg::Type::STR_HEX, /* opt */ false, /* default_val */ "", "The transaction id (must be in mempool)"}, + }} + .ToString() + "\nResult:\n" "{ (json object)\n" + EntryDescriptionString() @@ -670,10 +688,12 @@ static UniValue getblockhash(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 1) throw std::runtime_error( - "getblockhash height\n" - "\nReturns hash of block in best-block-chain at height provided.\n" - "\nArguments:\n" - "1. height (numeric, required) The height index\n" + RPCHelpMan{"getblockhash", + "\nReturns hash of block in best-block-chain at height provided.\n", + { + {"height", RPCArg::Type::NUM, /* opt */ false, /* default_val */ "", "The height index"}, + }} + .ToString() + "\nResult:\n" "\"hash\" (string) The block hash\n" "\nExamples:\n" @@ -695,12 +715,14 @@ static UniValue getblockheader(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw std::runtime_error( - "getblockheader \"hash\" ( verbose )\n" - "\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n" - "If verbose is true, returns an Object with information about blockheader <hash>.\n" - "\nArguments:\n" - "1. \"hash\" (string, required) The block hash\n" - "2. verbose (boolean, optional, default=true) true for a json object, false for the hex-encoded data\n" + RPCHelpMan{"getblockheader", + "\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n" + "If verbose is true, returns an Object with information about blockheader <hash>.\n", + { + {"blockhash", RPCArg::Type::STR_HEX, /* opt */ false, /* default_val */ "", "The block hash"}, + {"verbose", RPCArg::Type::BOOL, /* opt */ true, /* default_val */ "true", "true for a json object, false for the hex-encoded data"}, + }} + .ToString() + "\nResult (for verbose = true):\n" "{\n" " \"hash\" : \"hash\", (string) the block hash (same as provided)\n" @@ -773,13 +795,15 @@ static UniValue getblock(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw std::runtime_error( - "getblock \"blockhash\" ( verbosity ) \n" - "\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 <hash>.\n" - "If verbosity is 2, returns an Object with information about block <hash> and information about each transaction. \n" - "\nArguments:\n" - "1. \"blockhash\" (string, required) The block hash\n" - "2. verbosity (numeric, optional, default=1) 0 for hex-encoded data, 1 for a json object, and 2 for json object with transaction data\n" + 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 <hash>.\n" + "If verbosity is 2, returns an Object with information about block <hash> and information about each transaction. \n", + { + {"blockhash", RPCArg::Type::STR_HEX, /* opt */ false, /* default_val */ "", "The block hash"}, + {"verbosity", RPCArg::Type::NUM, /* opt */ true, /* default_val */ "1", "0 for hex-encoded data, 1 for a json object, and 2 for json object with transaction data"}, + }} + .ToString() + "\nResult (for verbosity = 0):\n" "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n" "\nResult (for verbosity = 1):\n" @@ -925,10 +949,12 @@ static UniValue pruneblockchain(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 1) throw std::runtime_error( - "pruneblockchain\n" - "\nArguments:\n" - "1. \"height\" (numeric, required) The block height to prune up to. May be set to a discrete height, or a unix timestamp\n" - " to prune blocks whose block time is at least 2 hours older than the provided timestamp.\n" + RPCHelpMan{"pruneblockchain", "", + { + {"height", RPCArg::Type::NUM, /* opt */ false, /* default_val */ "", "The block height to prune up to. May be set to a discrete height, or a unix timestamp\n" + " to prune blocks whose block time is at least 2 hours older than the provided timestamp."}, + }} + .ToString() + "\nResult:\n" "n (numeric) Height of the last block pruned.\n" "\nExamples:\n" @@ -974,9 +1000,11 @@ static UniValue gettxoutsetinfo(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 0) throw std::runtime_error( - "gettxoutsetinfo\n" - "\nReturns statistics about the unspent transaction output set.\n" - "Note this call may take some time.\n" + RPCHelpMan{"gettxoutsetinfo", + "\nReturns statistics about the unspent transaction output set.\n" + "Note this call may take some time.\n", + {}} + .ToString() + "\nResult:\n" "{\n" " \"height\":n, (numeric) The current block height (index)\n" @@ -1016,13 +1044,14 @@ UniValue gettxout(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) throw std::runtime_error( - "gettxout \"txid\" n ( include_mempool )\n" - "\nReturns details about an unspent transaction output.\n" - "\nArguments:\n" - "1. \"txid\" (string, required) The transaction id\n" - "2. \"n\" (numeric, required) vout number\n" - "3. \"include_mempool\" (boolean, optional) Whether to include the mempool. Default: true." - " Note that an unspent output that is spent in the mempool won't appear.\n" + RPCHelpMan{"gettxout", + "\nReturns details about an unspent transaction output.\n", + { + {"txid", RPCArg::Type::STR, /* opt */ false, /* default_val */ "", "The transaction id"}, + {"n", RPCArg::Type::NUM, /* opt */ false, /* default_val */ "", "vout number"}, + {"include_mempool", RPCArg::Type::BOOL, /* opt */ true, /* default_val */ "true", "Whether to include the mempool. Note that an unspent output that is spent in the mempool won't appear."}, + }} + .ToString() + "\nResult:\n" "{\n" " \"bestblock\": \"hash\", (string) The hash of the block at the tip of the chain\n" @@ -1096,11 +1125,13 @@ static UniValue verifychain(const JSONRPCRequest& request) int nCheckDepth = gArgs.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS); if (request.fHelp || request.params.size() > 2) throw std::runtime_error( - "verifychain ( checklevel nblocks )\n" - "\nVerifies blockchain database.\n" - "\nArguments:\n" - "1. checklevel (numeric, optional, 0-4, default=" + strprintf("%d", nCheckLevel) + ") How thorough the block verification is.\n" - "2. nblocks (numeric, optional, default=" + strprintf("%d", nCheckDepth) + ", 0=all) The number of blocks to check.\n" + RPCHelpMan{"verifychain", + "\nVerifies blockchain database.\n", + { + {"checklevel", RPCArg::Type::NUM, /* opt */ true, /* default_val */ strprintf("%d, range=0-4", nCheckLevel), "How thorough the block verification is."}, + {"nblocks", RPCArg::Type::NUM, /* opt */ true, /* default_val */ strprintf("%d, 0=all", nCheckDepth), "The number of blocks to check."}, + }} + .ToString() + "\nResult:\n" "true|false (boolean) Verified or not\n" "\nExamples:\n" @@ -1193,8 +1224,9 @@ UniValue getblockchaininfo(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 0) throw std::runtime_error( - "getblockchaininfo\n" - "Returns an object containing various state info regarding blockchain processing.\n" + RPCHelpMan{"getblockchaininfo", + "Returns an object containing various state info regarding blockchain processing.\n", {}} + .ToString() + "\nResult:\n" "{\n" " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n" @@ -1310,9 +1342,11 @@ static UniValue getchaintips(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 0) throw std::runtime_error( - "getchaintips\n" - "Return information about all known tips in the block tree," - " including the main chain as well as orphaned branches.\n" + RPCHelpMan{"getchaintips", + "Return information about all known tips in the block tree," + " including the main chain as well as orphaned branches.\n", + {}} + .ToString() + "\nResult:\n" "[\n" " {\n" @@ -1388,7 +1422,7 @@ static UniValue getchaintips(const JSONRPCRequest& request) } else if (block->nStatus & BLOCK_FAILED_MASK) { // This block or one of its ancestors is invalid. status = "invalid"; - } else if (block->nChainTx == 0) { + } else if (!block->HaveTxsDownloaded()) { // This block cannot be connected because full block data for it or one of its parents is missing. status = "headers-only"; } else if (block->IsValid(BLOCK_VALID_SCRIPTS)) { @@ -1427,8 +1461,9 @@ static UniValue getmempoolinfo(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 0) throw std::runtime_error( - "getmempoolinfo\n" - "\nReturns details on the active state of the TX memory pool.\n" + RPCHelpMan{"getmempoolinfo", + "\nReturns details on the active state of the TX memory pool.\n", {}} + .ToString() + "\nResult:\n" "{\n" " \"size\": xxxxx, (numeric) Current tx count\n" @@ -1450,12 +1485,14 @@ static UniValue preciousblock(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 1) throw std::runtime_error( - "preciousblock \"blockhash\"\n" - "\nTreats a block as if it were received before others with the same work.\n" - "\nA later preciousblock call can override the effect of an earlier one.\n" - "\nThe effects of preciousblock are not retained across restarts.\n" - "\nArguments:\n" - "1. \"blockhash\" (string, required) the hash of the block to mark as precious\n" + RPCHelpMan{"preciousblock", + "\nTreats a block as if it were received before others with the same work.\n" + "\nA later preciousblock call can override the effect of an earlier one.\n" + "\nThe effects of preciousblock are not retained across restarts.\n", + { + {"blockhash", RPCArg::Type::STR_HEX, /* opt */ false, /* default_val */ "", "the hash of the block to mark as precious"}, + }} + .ToString() + "\nResult:\n" "\nExamples:\n" + HelpExampleCli("preciousblock", "\"blockhash\"") @@ -1487,10 +1524,12 @@ static UniValue invalidateblock(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 1) throw std::runtime_error( - "invalidateblock \"blockhash\"\n" - "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n" - "\nArguments:\n" - "1. \"blockhash\" (string, required) the hash of the block to mark as invalid\n" + RPCHelpMan{"invalidateblock", + "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n", + { + {"blockhash", RPCArg::Type::STR_HEX, /* opt */ false, /* default_val */ "", "the hash of the block to mark as invalid"}, + }} + .ToString() + "\nResult:\n" "\nExamples:\n" + HelpExampleCli("invalidateblock", "\"blockhash\"") @@ -1525,11 +1564,13 @@ static UniValue reconsiderblock(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 1) throw std::runtime_error( - "reconsiderblock \"blockhash\"\n" - "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n" - "This can be used to undo the effects of invalidateblock.\n" - "\nArguments:\n" - "1. \"blockhash\" (string, required) the hash of the block to reconsider\n" + RPCHelpMan{"reconsiderblock", + "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n" + "This can be used to undo the effects of invalidateblock.\n", + { + {"blockhash", RPCArg::Type::STR_HEX, /* opt */ false, /* default_val */ "", "the hash of the block to reconsider"}, + }} + .ToString() + "\nResult:\n" "\nExamples:\n" + HelpExampleCli("reconsiderblock", "\"blockhash\"") @@ -1562,11 +1603,13 @@ static UniValue getchaintxstats(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() > 2) throw std::runtime_error( - "getchaintxstats ( nblocks blockhash )\n" - "\nCompute statistics about the total number and rate of transactions in the chain.\n" - "\nArguments:\n" - "1. nblocks (numeric, optional) Size of the window in number of blocks (default: one month).\n" - "2. \"blockhash\" (string, optional) The hash of the block that ends the window.\n" + RPCHelpMan{"getchaintxstats", + "\nCompute statistics about the total number and rate of transactions in the chain.\n", + { + {"nblocks", RPCArg::Type::NUM, /* opt */ true, /* default_val */ "one month", "Size of the window in number of blocks"}, + {"blockhash", RPCArg::Type::STR_HEX, /* opt */ true, /* default_val */ "chain tip", "The hash of the block that ends the window."}, + }} + .ToString() + "\nResult:\n" "{\n" " \"time\": xxxxx, (numeric) The timestamp for the final block in the window in UNIX format.\n" @@ -1692,18 +1735,20 @@ static UniValue getblockstats(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) { throw std::runtime_error( - "getblockstats hash_or_height ( stats )\n" - "\nCompute per block statistics for a given window. All amounts are in satoshis.\n" - "It won't work for some heights with pruning.\n" - "It won't work without -txindex for utxo_size_inc, *fee or *feerate stats.\n" - "\nArguments:\n" - "1. \"hash_or_height\" (string or numeric, required) The block hash or height of the target block\n" - "2. \"stats\" (array, optional) Values to plot, by default all values (see result below)\n" - " [\n" - " \"height\", (string, optional) Selected statistic\n" - " \"time\", (string, optional) Selected statistic\n" - " ,...\n" - " ]\n" + RPCHelpMan{"getblockstats", + "\nCompute per block statistics for a given window. All amounts are in satoshis.\n" + "It won't work for some heights with pruning.\n" + "It won't work without -txindex for utxo_size_inc, *fee or *feerate stats.\n", + { + {"hash_or_height", RPCArg::Type::NUM, /* opt */ false, /* default_val */ "", "The block hash or height of the target block", "", {"", "string or numeric"}}, + {"stats", RPCArg::Type::ARR, /* opt */ true, /* default_val */ "all values", "Values to plot (see result below)", + { + {"height", RPCArg::Type::STR, /* opt */ true, /* default_val */ "", "Selected statistic"}, + {"time", RPCArg::Type::STR, /* opt */ true, /* default_val */ "", "Selected statistic"}, + }, + "stats"}, + }} + .ToString() + "\nResult:\n" "{ (json object)\n" " \"avgfee\": xxxxx, (numeric) Average fee in the block\n" @@ -1956,8 +2001,9 @@ static UniValue savemempool(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 0) { throw std::runtime_error( - "savemempool\n" - "\nDumps the mempool to disk. It will fail until the previous dump is fully loaded.\n" + RPCHelpMan{"savemempool", + "\nDumps the mempool to disk. It will fail until the previous dump is fully loaded.\n", {}} + .ToString() + "\nExamples:\n" + HelpExampleCli("savemempool", "") + HelpExampleRpc("savemempool", "") @@ -2039,34 +2085,39 @@ UniValue scantxoutset(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw std::runtime_error( - "scantxoutset <action> ( <scanobjects> )\n" - "\nEXPERIMENTAL warning: this call may be removed or changed in future releases.\n" - "\nScans the unspent transaction output set for entries that match certain output descriptors.\n" - "Examples of output descriptors are:\n" - " addr(<address>) Outputs whose scriptPubKey corresponds to the specified address (does not include P2PK)\n" - " raw(<hex script>) Outputs whose scriptPubKey equals the specified hex scripts\n" - " combo(<pubkey>) P2PK, P2PKH, P2WPKH, and P2SH-P2WPKH outputs for the given pubkey\n" - " pkh(<pubkey>) P2PKH outputs for the given pubkey\n" - " sh(multi(<n>,<pubkey>,<pubkey>,...)) P2SH-multisig outputs for the given threshold and pubkeys\n" - "\nIn the above, <pubkey> either refers to a fixed public key in hexadecimal notation, or to an xpub/xprv optionally followed by one\n" - "or more path elements separated by \"/\", and optionally ending in \"/*\" (unhardened), or \"/*'\" or \"/*h\" (hardened) to specify all\n" - "unhardened or hardened child keys.\n" - "In the latter case, a range needs to be specified by below if different from 1000.\n" - "For more information on output descriptors, see the documentation in the doc/descriptors.md file.\n" - "\nArguments:\n" - "1. \"action\" (string, required) The action to execute\n" + RPCHelpMan{"scantxoutset", + "\nEXPERIMENTAL warning: this call may be removed or changed in future releases.\n" + "\nScans the unspent transaction output set for entries that match certain output descriptors.\n" + "Examples of output descriptors are:\n" + " addr(<address>) Outputs whose scriptPubKey corresponds to the specified address (does not include P2PK)\n" + " raw(<hex script>) Outputs whose scriptPubKey equals the specified hex scripts\n" + " combo(<pubkey>) P2PK, P2PKH, P2WPKH, and P2SH-P2WPKH outputs for the given pubkey\n" + " pkh(<pubkey>) P2PKH outputs for the given pubkey\n" + " sh(multi(<n>,<pubkey>,<pubkey>,...)) P2SH-multisig outputs for the given threshold and pubkeys\n" + "\nIn the above, <pubkey> either refers to a fixed public key in hexadecimal notation, or to an xpub/xprv optionally followed by one\n" + "or more path elements separated by \"/\", and optionally ending in \"/*\" (unhardened), or \"/*'\" or \"/*h\" (hardened) to specify all\n" + "unhardened or hardened child keys.\n" + "In the latter case, a range needs to be specified by below if different from 1000.\n" + "For more information on output descriptors, see the documentation in the doc/descriptors.md file.\n", + { + {"action", RPCArg::Type::STR, /* opt */ false, /* default_val */ "", "The action to execute\n" " \"start\" for starting a scan\n" " \"abort\" for aborting the current scan (returns true when abort was successful)\n" - " \"status\" for progress report (in %) of the current scan\n" - "2. \"scanobjects\" (array, required) Array of scan objects\n" - " [ Every scan object is either a string descriptor or an object:\n" - " \"descriptor\", (string, optional) An output descriptor\n" - " { (object, optional) An object with output descriptor and metadata\n" - " \"desc\": \"descriptor\", (string, required) An output descriptor\n" - " \"range\": n, (numeric, optional) Up to what child index HD chains should be explored (default: 1000)\n" - " },\n" - " ...\n" - " ]\n" + " \"status\" for progress report (in %) of the current scan"}, + {"scanobjects", RPCArg::Type::ARR, /* opt */ false, /* default_val */ "", "Array of scan objects\n" + " Every scan object is either a string descriptor or an object:", + { + {"descriptor", RPCArg::Type::STR, /* opt */ true, /* default_val */ "", "An output descriptor"}, + {"", RPCArg::Type::OBJ, /* opt */ true, /* default_val */ "", "An object with output descriptor and metadata", + { + {"desc", RPCArg::Type::STR, /* opt */ false, /* default_val */ "", "An output descriptor"}, + {"range", RPCArg::Type::NUM, /* opt */ true, /* default_val */ "1000", "Up to what child index HD chains should be explored"}, + }, + }, + }, + "[scanobjects,...]"}, + }} + .ToString() + "\nResult:\n" "{\n" " \"unspents\": [\n" @@ -2074,6 +2125,7 @@ UniValue scantxoutset(const JSONRPCRequest& request) " \"txid\" : \"transactionid\", (string) The transaction id\n" " \"vout\": n, (numeric) the vout value\n" " \"scriptPubKey\" : \"script\", (string) the script key\n" + " \"desc\" : \"descriptor\", (string) A specialized descriptor for the matched scriptPubKey\n" " \"amount\" : x.xxx, (numeric) The total amount in " + CURRENCY_UNIT + " of the unspent output\n" " \"height\" : n, (numeric) Height of the unspent transaction output\n" " }\n" @@ -2108,6 +2160,7 @@ UniValue scantxoutset(const JSONRPCRequest& request) throw JSONRPCError(RPC_INVALID_PARAMETER, "Scan already in progress, use action \"abort\" or \"status\""); } std::set<CScript> needles; + std::map<CScript, std::string> descriptors; CAmount total_in = 0; // loop through the scan objects @@ -2140,7 +2193,11 @@ UniValue scantxoutset(const JSONRPCRequest& request) if (!desc->Expand(i, provider, scripts, provider)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Cannot derive script without private keys: '%s'", desc_str)); } - needles.insert(scripts.begin(), scripts.end()); + for (const auto& script : scripts) { + std::string inferred = InferDescriptor(script, provider)->ToString(); + needles.emplace(script); + descriptors.emplace(std::move(script), std::move(inferred)); + } } } @@ -2173,6 +2230,7 @@ UniValue scantxoutset(const JSONRPCRequest& request) unspent.pushKV("txid", outpoint.hash.GetHex()); unspent.pushKV("vout", (int32_t)outpoint.n); unspent.pushKV("scriptPubKey", HexStr(txo.scriptPubKey.begin(), txo.scriptPubKey.end())); + unspent.pushKV("desc", descriptors[txo.scriptPubKey]); unspent.pushKV("amount", ValueFromAmount(txo.nValue)); unspent.pushKV("height", (int32_t)coin.nHeight); |