From 1bde72a219f8ac09a19410f739f7f69a0e2ce800 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Wed, 4 Feb 2026 23:44:42 +0700 Subject: [PATCH 1/2] fmt: unify formatting for RPC code with Bitcoin Core It's a follow-up for #14726, bitcoin#25029 and other backports Formatting is synced up with state at Bitcoin Core v26 (most backports up to this version is done) --- src/rpc/blockchain.cpp | 651 ++++++++++++++++++------------------- src/rpc/fees.cpp | 192 +++++------ src/rpc/mempool.cpp | 62 ++-- src/rpc/mining.cpp | 121 +++---- src/rpc/net.cpp | 174 +++++----- src/rpc/node.cpp | 148 ++++----- src/rpc/output_script.cpp | 298 ++++++++--------- src/rpc/rawtransaction.cpp | 424 ++++++++++++------------ src/rpc/server.cpp | 65 ++-- src/rpc/signmessage.cpp | 69 ++-- src/rpc/txoutproof.cpp | 180 +++++----- 11 files changed, 1190 insertions(+), 1194 deletions(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index ab74d75431b9..f1e24ae0d328 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -208,15 +208,15 @@ UniValue blockToJSON(BlockManager& blockman, const CBlock& block, const CBlockIn static RPCHelpMan getblockcount() { return RPCHelpMan{"getblockcount", - "\nReturns the height of the most-work fully-validated chain.\n" - "The genesis block has height 0.\n", - {}, - RPCResult{ - RPCResult::Type::NUM, "", "The current block count"}, - RPCExamples{ - HelpExampleCli("getblockcount", "") - + HelpExampleRpc("getblockcount", "") - }, + "\nReturns the height of the most-work fully-validated chain.\n" + "The genesis block has height 0.\n", + {}, + RPCResult{ + RPCResult::Type::NUM, "", "The current block count"}, + RPCExamples{ + HelpExampleCli("getblockcount", "") + + HelpExampleRpc("getblockcount", "") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { ChainstateManager& chainman = EnsureAnyChainman(request.context); @@ -229,15 +229,15 @@ static RPCHelpMan getblockcount() static RPCHelpMan getbestblockhash() { return RPCHelpMan{"getbestblockhash", - "\nReturns the hash of the best (tip) block in the most-work fully-validated chain.\n", - {}, - RPCResult{ - RPCResult::Type::STR_HEX, "", "the block hash, hex-encoded"}, - RPCExamples{ - HelpExampleCli("getbestblockhash", "") - + HelpExampleRpc("getbestblockhash", "") - }, - [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue + "\nReturns the hash of the best (tip) block in the most-work fully-validated chain.\n", + {}, + RPCResult{ + RPCResult::Type::STR_HEX, "", "the block hash, hex-encoded"}, + RPCExamples{ + HelpExampleCli("getbestblockhash", "") + + HelpExampleRpc("getbestblockhash", "") + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { ChainstateManager& chainman = EnsureAnyChainman(request.context); LOCK(cs_main); @@ -308,21 +308,21 @@ void RPCNotifyBlockChange(const CBlockIndex* pindex) static 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", - { - {"timeout", RPCArg::Type::NUM, RPCArg::Default{0}, "Time in milliseconds to wait for a response. 0 indicates no timeout."}, - }, - RPCResult{ - RPCResult::Type::OBJ, "", "", - { - {RPCResult::Type::STR_HEX, "hash", "The blockhash"}, - {RPCResult::Type::NUM, "height", "Block height"}, - }}, - RPCExamples{ - HelpExampleCli("waitfornewblock", "1000") - + HelpExampleRpc("waitfornewblock", "1000") - }, + "\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, RPCArg::Default{0}, "Time in milliseconds to wait for a response. 0 indicates no timeout."}, + }, + RPCResult{ + RPCResult::Type::OBJ, "", "", + { + {RPCResult::Type::STR_HEX, "hash", "The blockhash"}, + {RPCResult::Type::NUM, "height", "Block height"}, + }}, + RPCExamples{ + HelpExampleCli("waitfornewblock", "1000") + + HelpExampleRpc("waitfornewblock", "1000") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { int timeout = 0; @@ -350,22 +350,22 @@ static RPCHelpMan waitfornewblock() static 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", - { - {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Block hash to wait for."}, - {"timeout", RPCArg::Type::NUM, RPCArg::Default{0}, "Time in milliseconds to wait for a response. 0 indicates no timeout."}, - }, - RPCResult{ - RPCResult::Type::OBJ, "", "", - { - {RPCResult::Type::STR_HEX, "hash", "The blockhash"}, - {RPCResult::Type::NUM, "height", "Block height"}, - }}, - RPCExamples{ - HelpExampleCli("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\" 1000") - + HelpExampleRpc("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000") - }, + "\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, RPCArg::Optional::NO, "Block hash to wait for."}, + {"timeout", RPCArg::Type::NUM, RPCArg::Default{0}, "Time in milliseconds to wait for a response. 0 indicates no timeout."}, + }, + RPCResult{ + RPCResult::Type::OBJ, "", "", + { + {RPCResult::Type::STR_HEX, "hash", "The blockhash"}, + {RPCResult::Type::NUM, "height", "Block height"}, + }}, + RPCExamples{ + HelpExampleCli("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\" 1000") + + HelpExampleRpc("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { int timeout = 0; @@ -396,23 +396,23 @@ static RPCHelpMan waitforblock() static 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", - { - {"height", RPCArg::Type::NUM, RPCArg::Optional::NO, "Block height to wait for."}, - {"timeout", RPCArg::Type::NUM, RPCArg::Default{0}, "Time in milliseconds to wait for a response. 0 indicates no timeout."}, - }, - RPCResult{ - RPCResult::Type::OBJ, "", "", - { - {RPCResult::Type::STR_HEX, "hash", "The blockhash"}, - {RPCResult::Type::NUM, "height", "Block height"}, - }}, - RPCExamples{ - HelpExampleCli("waitforblockheight", "100 1000") - + HelpExampleRpc("waitforblockheight", "100, 1000") - }, + "\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, RPCArg::Optional::NO, "Block height to wait for."}, + {"timeout", RPCArg::Type::NUM, RPCArg::Default{0}, "Time in milliseconds to wait for a response. 0 indicates no timeout."}, + }, + RPCResult{ + RPCResult::Type::OBJ, "", "", + { + {RPCResult::Type::STR_HEX, "hash", "The blockhash"}, + {RPCResult::Type::NUM, "height", "Block height"}, + }}, + RPCExamples{ + HelpExampleCli("waitforblockheight", "100 1000") + + HelpExampleRpc("waitforblockheight", "100, 1000") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { int timeout = 0; @@ -442,13 +442,13 @@ static RPCHelpMan waitforblockheight() static 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, "", ""}, - RPCExamples{ - HelpExampleCli("syncwithvalidationinterfacequeue","") - + HelpExampleRpc("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, "", ""}, + RPCExamples{ + HelpExampleCli("syncwithvalidationinterfacequeue","") + + HelpExampleRpc("syncwithvalidationinterfacequeue","") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { SyncWithValidationInterfaceQueue(); @@ -460,15 +460,15 @@ static RPCHelpMan syncwithvalidationinterfacequeue() static RPCHelpMan getdifficulty() { return RPCHelpMan{"getdifficulty", - "\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n", - {}, - RPCResult{ - RPCResult::Type::NUM, "", "the proof-of-work difficulty as a multiple of the minimum difficulty."}, - RPCExamples{ - HelpExampleCli("getdifficulty", "") - + HelpExampleRpc("getdifficulty", "") - }, - [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue + "\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n", + {}, + RPCResult{ + RPCResult::Type::NUM, "", "the proof-of-work difficulty as a multiple of the minimum difficulty."}, + RPCExamples{ + HelpExampleCli("getdifficulty", "") + + HelpExampleRpc("getdifficulty", "") + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { ChainstateManager& chainman = EnsureAnyChainman(request.context); @@ -574,17 +574,17 @@ static RPCHelpMan getblockhashes() static 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"}, - }, - RPCResult{ - RPCResult::Type::STR_HEX, "", "The block hash"}, - RPCExamples{ - HelpExampleCli("getblockhash", "1000") - + HelpExampleRpc("getblockhash", "1000") - }, - [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue + "\nReturns hash of block in best-block-chain at height provided.\n", + { + {"height", RPCArg::Type::NUM, RPCArg::Optional::NO, "The height index"}, + }, + RPCResult{ + RPCResult::Type::STR_HEX, "", "The block hash"}, + RPCExamples{ + HelpExampleCli("getblockhash", "1000") + + HelpExampleRpc("getblockhash", "1000") + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { ChainstateManager& chainman = EnsureAnyChainman(request.context); LOCK(cs_main); @@ -603,41 +603,41 @@ static RPCHelpMan getblockhash() static 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", - { - {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The block hash"}, - {"verbose", RPCArg::Type::BOOL, RPCArg::Default{true}, "true for a json object, false for the hex-encoded data"}, - }, - { - RPCResult{"for verbose = true", - RPCResult::Type::OBJ, "", "", + "\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", { - {RPCResult::Type::STR_HEX, "hash", "the block hash (same as provided)"}, - {RPCResult::Type::NUM, "confirmations", "The number of confirmations, or -1 if the block is not on the main chain"}, - {RPCResult::Type::NUM, "height", "The block height or index"}, - {RPCResult::Type::NUM, "version", "The block version"}, - {RPCResult::Type::STR_HEX, "versionHex", "The block version formatted in hexadecimal"}, - {RPCResult::Type::STR_HEX, "merkleroot", "The merkle root"}, - {RPCResult::Type::NUM_TIME, "time", "The block time expressed in " + UNIX_EPOCH_TIME}, - {RPCResult::Type::NUM_TIME, "mediantime", "The median block time expressed in " + UNIX_EPOCH_TIME}, - {RPCResult::Type::NUM, "nonce", "The nonce"}, - {RPCResult::Type::STR_HEX, "bits", "The bits"}, - {RPCResult::Type::NUM, "difficulty", "The difficulty"}, - {RPCResult::Type::STR_HEX, "chainwork", "Expected number of hashes required to produce the current chain"}, - {RPCResult::Type::NUM, "nTx", "The number of transactions in the block"}, - {RPCResult::Type::STR_HEX, "previousblockhash", /*optional=*/true, "The hash of the previous block (if available)"}, - {RPCResult::Type::STR_HEX, "nextblockhash", /*optional=*/true, "The hash of the next block (if available)"}, - {RPCResult::Type::BOOL, "chainlock", "The state of the block ChainLock"}, - }}, - RPCResult{"for verbose=false", - RPCResult::Type::STR_HEX, "", "A string that is serialized, hex-encoded data for block 'hash'"}, - }, - RPCExamples{ - HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") - + HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") - }, - [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue + {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The block hash"}, + {"verbose", RPCArg::Type::BOOL, RPCArg::Default{true}, "true for a json object, false for the hex-encoded data"}, + }, + { + RPCResult{"for verbose = true", + RPCResult::Type::OBJ, "", "", + { + {RPCResult::Type::STR_HEX, "hash", "the block hash (same as provided)"}, + {RPCResult::Type::NUM, "confirmations", "The number of confirmations, or -1 if the block is not on the main chain"}, + {RPCResult::Type::NUM, "height", "The block height or index"}, + {RPCResult::Type::NUM, "version", "The block version"}, + {RPCResult::Type::STR_HEX, "versionHex", "The block version formatted in hexadecimal"}, + {RPCResult::Type::STR_HEX, "merkleroot", "The merkle root"}, + {RPCResult::Type::NUM_TIME, "time", "The block time expressed in " + UNIX_EPOCH_TIME}, + {RPCResult::Type::NUM_TIME, "mediantime", "The median block time expressed in " + UNIX_EPOCH_TIME}, + {RPCResult::Type::NUM, "nonce", "The nonce"}, + {RPCResult::Type::STR_HEX, "bits", "The bits"}, + {RPCResult::Type::NUM, "difficulty", "The difficulty"}, + {RPCResult::Type::STR_HEX, "chainwork", "Expected number of hashes required to produce the current chain"}, + {RPCResult::Type::NUM, "nTx", "The number of transactions in the block"}, + {RPCResult::Type::STR_HEX, "previousblockhash", /*optional=*/true, "The hash of the previous block (if available)"}, + {RPCResult::Type::STR_HEX, "nextblockhash", /*optional=*/true, "The hash of the next block (if available)"}, + {RPCResult::Type::BOOL, "chainlock", "The state of the block ChainLock"}, + }}, + RPCResult{"for verbose=false", + RPCResult::Type::STR_HEX, "", "A string that is serialized, hex-encoded data for block 'hash'"}, + }, + RPCExamples{ + HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") + + HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { uint256 hash(ParseHashV(request.params[0], "hash")); const NodeContext& node = EnsureAnyNodeContext(request.context); @@ -932,44 +932,44 @@ static RPCHelpMan getblock() }, { RPCResult{"for verbosity = 0", - RPCResult::Type::STR_HEX, "", "A string that is serialized, hex-encoded data for block 'hash'"}, + RPCResult::Type::STR_HEX, "", "A string that is serialized, hex-encoded data for block 'hash'"}, RPCResult{"for verbosity = 1", - RPCResult::Type::OBJ, "", "", - { - {RPCResult::Type::STR_HEX, "hash", "the block hash (same as provided)"}, - {RPCResult::Type::NUM, "confirmations", "The number of confirmations, or -1 if the block is not on the main chain"}, - {RPCResult::Type::NUM, "height", "The block height or index"}, - {RPCResult::Type::NUM, "version", "The block version"}, - {RPCResult::Type::STR_HEX, "versionHex", "The block version formatted in hexadecimal"}, - {RPCResult::Type::STR_HEX, "merkleroot", "The merkle root"}, - {RPCResult::Type::NUM_TIME, "time", "The block time expressed in " + UNIX_EPOCH_TIME}, - {RPCResult::Type::NUM_TIME, "mediantime", "The median block time expressed in " + UNIX_EPOCH_TIME}, - {RPCResult::Type::NUM, "nonce", "The nonce"}, - {RPCResult::Type::STR_HEX, "bits", "The bits"}, - {RPCResult::Type::NUM, "difficulty", "The difficulty"}, - {RPCResult::Type::STR_HEX, "chainwork", "Expected number of hashes required to produce the current chain"}, - {RPCResult::Type::NUM, "nTx", "The number of transactions in the block"}, - {RPCResult::Type::STR_HEX, "previousblockhash", /*optional=*/true, "The hash of the previous block (if available)"}, - {RPCResult::Type::STR_HEX, "nextblockhash", /*optional=*/true, "The hash of the next block (if available)"}, - {RPCResult::Type::BOOL, "chainlock", "The state of the block ChainLock"}, - {RPCResult::Type::NUM, "size", "The block size"}, - {RPCResult::Type::ARR, "tx", "The transaction ids", - {{RPCResult::Type::STR_HEX, "", "The transaction id"}}}, - CCbTx::GetJsonHelp(/*key=*/"cbTx", /*optional=*/true), - }}, + RPCResult::Type::OBJ, "", "", + { + {RPCResult::Type::STR_HEX, "hash", "the block hash (same as provided)"}, + {RPCResult::Type::NUM, "confirmations", "The number of confirmations, or -1 if the block is not on the main chain"}, + {RPCResult::Type::NUM, "height", "The block height or index"}, + {RPCResult::Type::NUM, "version", "The block version"}, + {RPCResult::Type::STR_HEX, "versionHex", "The block version formatted in hexadecimal"}, + {RPCResult::Type::STR_HEX, "merkleroot", "The merkle root"}, + {RPCResult::Type::NUM_TIME, "time", "The block time expressed in " + UNIX_EPOCH_TIME}, + {RPCResult::Type::NUM_TIME, "mediantime", "The median block time expressed in " + UNIX_EPOCH_TIME}, + {RPCResult::Type::NUM, "nonce", "The nonce"}, + {RPCResult::Type::STR_HEX, "bits", "The bits"}, + {RPCResult::Type::NUM, "difficulty", "The difficulty"}, + {RPCResult::Type::STR_HEX, "chainwork", "Expected number of hashes required to produce the current chain"}, + {RPCResult::Type::NUM, "nTx", "The number of transactions in the block"}, + {RPCResult::Type::STR_HEX, "previousblockhash", /*optional=*/true, "The hash of the previous block (if available)"}, + {RPCResult::Type::STR_HEX, "nextblockhash", /*optional=*/true, "The hash of the next block (if available)"}, + {RPCResult::Type::BOOL, "chainlock", "The state of the block ChainLock"}, + {RPCResult::Type::NUM, "size", "The block size"}, + {RPCResult::Type::ARR, "tx", "The transaction ids", + {{RPCResult::Type::STR_HEX, "", "The transaction id"}}}, + CCbTx::GetJsonHelp(/*key=*/"cbTx", /*optional=*/true), + }}, RPCResult{"for verbosity = 2", - RPCResult::Type::OBJ, "", "", + RPCResult::Type::OBJ, "", "", + { + {RPCResult::Type::ELISION, "", "Same output as verbosity = 1"}, + {RPCResult::Type::ARR, "tx", "", + { + {RPCResult::Type::OBJ, "", "", { - {RPCResult::Type::ELISION, "", "Same output as verbosity = 1"}, - {RPCResult::Type::ARR, "tx", "", - { - {RPCResult::Type::OBJ, "", "", - { - {RPCResult::Type::ELISION, "", "The transactions in the format of the getrawtransaction RPC. Different from verbosity = 1 \"tx\" result"}, - {RPCResult::Type::NUM, "fee", "The transaction fee in " + CURRENCY_UNIT + ", omitted if block undo data is not available"}, - }}, - }}, + {RPCResult::Type::ELISION, "", "The transactions in the format of the getrawtransaction RPC. Different from verbosity = 1 \"tx\" result"}, + {RPCResult::Type::NUM, "fee", "The transaction fee in " + CURRENCY_UNIT + ", omitted if block undo data is not available"}, }}, + }}, + }}, RPCResult{"for verbosity = 3", RPCResult::Type::OBJ, "", "", { @@ -982,7 +982,7 @@ static RPCHelpMan getblock() }}, }}, }}, - }, + }, RPCExamples{ HelpExampleCli("getblock", "\"00000000000fd08c2fb661d2fcb0d49abb3a91e5f27082ce64feed3b4dede2e2\"") + HelpExampleRpc("getblock", "\"00000000000fd08c2fb661d2fcb0d49abb3a91e5f27082ce64feed3b4dede2e2\"") @@ -1044,16 +1044,16 @@ static RPCHelpMan getblock() static 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."}, - }, - RPCResult{ - RPCResult::Type::NUM, "", "Height of the last block pruned"}, - RPCExamples{ - HelpExampleCli("pruneblockchain", "1000") - + HelpExampleRpc("pruneblockchain", "1000") - }, + { + {"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."}, + }, + RPCResult{ + RPCResult::Type::NUM, "", "Height of the last block pruned"}, + RPCExamples{ + HelpExampleCli("pruneblockchain", "1000") + + HelpExampleRpc("pruneblockchain", "1000") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { if (!node::fPruneMode) @@ -1141,52 +1141,52 @@ std::optional GetUTXOStats(CCoinsView* view, node::BlockMan static 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", - { - {"hash_type", RPCArg::Type::STR, RPCArg::Default{"hash_serialized_2"}, "Which UTXO set hash should be calculated. Options: 'hash_serialized_2' (the legacy algorithm), 'muhash', 'none'."}, - {"hash_or_height", RPCArg::Type::NUM, RPCArg::DefaultHint{"the current best block"}, "The block hash or height of the target height (only available with coinstatsindex).", "", {"", "string or numeric"}}, - {"use_index", RPCArg::Type::BOOL, RPCArg::Default{true}, "Use coinstatsindex, if available."}, - }, - RPCResult{ - RPCResult::Type::OBJ, "", "", - { - {RPCResult::Type::NUM, "height", "The block height (index) of the returned statistics"}, - {RPCResult::Type::STR_HEX, "bestblock", "The hash of the block at which these statistics are calculated"}, - {RPCResult::Type::NUM, "txouts", "The number of unspent transaction outputs"}, - {RPCResult::Type::NUM, "bogosize", "Database-independent, meaningless metric indicating the UTXO set size"}, - {RPCResult::Type::STR_HEX, "hash_serialized_2", /*optional=*/true, "The serialized hash (only present if 'hash_serialized_2' hash_type is chosen)"}, - {RPCResult::Type::STR_HEX, "muhash", /*optional=*/true, "The serialized hash (only present if 'muhash' hash_type is chosen)"}, - {RPCResult::Type::NUM, "transactions", /*optional=*/true, "The number of transactions with unspent outputs (not available when coinstatsindex is used)"}, - {RPCResult::Type::NUM, "disk_size", /*optional=*/true, "The estimated size of the chainstate on disk (not available when coinstatsindex is used)"}, - {RPCResult::Type::STR_AMOUNT, "total_amount", "The total amount of coins in the UTXO set"}, - {RPCResult::Type::STR_AMOUNT, "total_unspendable_amount", /*optional=*/true, "The total amount of coins permanently excluded from the UTXO set (only available if coinstatsindex is used)"}, - {RPCResult::Type::OBJ, "block_info", /*optional=*/true, "Info on amounts in the block at this block height (only available if coinstatsindex is used)", + "\nReturns statistics about the unspent transaction output set.\n" + "Note this call may take some time if you are not using coinstatsindex.\n", { - {RPCResult::Type::STR_AMOUNT, "prevout_spent", "Total amount of all prevouts spent in this block"}, - {RPCResult::Type::STR_AMOUNT, "coinbase", "Coinbase subsidy amount of this block"}, - {RPCResult::Type::STR_AMOUNT, "new_outputs_ex_coinbase", "Total amount of new outputs created by this block"}, - {RPCResult::Type::STR_AMOUNT, "unspendable", "Total amount of unspendable outputs created in this block"}, - {RPCResult::Type::OBJ, "unspendables", "Detailed view of the unspendable categories", + {"hash_type", RPCArg::Type::STR, RPCArg::Default{"hash_serialized_2"}, "Which UTXO set hash should be calculated. Options: 'hash_serialized_2' (the legacy algorithm), 'muhash', 'none'."}, + {"hash_or_height", RPCArg::Type::NUM, RPCArg::DefaultHint{"the current best block"}, "The block hash or height of the target height (only available with coinstatsindex).", "", {"", "string or numeric"}}, + {"use_index", RPCArg::Type::BOOL, RPCArg::Default{true}, "Use coinstatsindex, if available."}, + }, + RPCResult{ + RPCResult::Type::OBJ, "", "", { - {RPCResult::Type::STR_AMOUNT, "genesis_block", "The unspendable amount of the Genesis block subsidy"}, - {RPCResult::Type::STR_AMOUNT, "bip30", "Transactions overridden by duplicates (no longer possible with BIP30)"}, - {RPCResult::Type::STR_AMOUNT, "scripts", "Amounts sent to scripts that are unspendable (for example OP_RETURN outputs)"}, - {RPCResult::Type::STR_AMOUNT, "unclaimed_rewards", "Fee rewards that miners did not claim in their coinbase transaction"}, - }} - }}, - }}, - RPCExamples{ - HelpExampleCli("gettxoutsetinfo", "") + - HelpExampleCli("gettxoutsetinfo", R"("none")") + - HelpExampleCli("gettxoutsetinfo", R"("none" 1000)") + - HelpExampleCli("gettxoutsetinfo", R"("none" '"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09"')") + - HelpExampleCli("-named gettxoutsetinfo", R"(hash_type='muhash' use_index='false')") + - HelpExampleRpc("gettxoutsetinfo", "") + - HelpExampleRpc("gettxoutsetinfo", R"("none")") + - HelpExampleRpc("gettxoutsetinfo", R"("none", 1000)") + - HelpExampleRpc("gettxoutsetinfo", R"("none", "00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09")") - }, + {RPCResult::Type::NUM, "height", "The block height (index) of the returned statistics"}, + {RPCResult::Type::STR_HEX, "bestblock", "The hash of the block at which these statistics are calculated"}, + {RPCResult::Type::NUM, "txouts", "The number of unspent transaction outputs"}, + {RPCResult::Type::NUM, "bogosize", "Database-independent, meaningless metric indicating the UTXO set size"}, + {RPCResult::Type::STR_HEX, "hash_serialized_2", /*optional=*/true, "The serialized hash (only present if 'hash_serialized_2' hash_type is chosen)"}, + {RPCResult::Type::STR_HEX, "muhash", /*optional=*/true, "The serialized hash (only present if 'muhash' hash_type is chosen)"}, + {RPCResult::Type::NUM, "transactions", /*optional=*/true, "The number of transactions with unspent outputs (not available when coinstatsindex is used)"}, + {RPCResult::Type::NUM, "disk_size", /*optional=*/true, "The estimated size of the chainstate on disk (not available when coinstatsindex is used)"}, + {RPCResult::Type::STR_AMOUNT, "total_amount", "The total amount of coins in the UTXO set"}, + {RPCResult::Type::STR_AMOUNT, "total_unspendable_amount", /*optional=*/true, "The total amount of coins permanently excluded from the UTXO set (only available if coinstatsindex is used)"}, + {RPCResult::Type::OBJ, "block_info", /*optional=*/true, "Info on amounts in the block at this block height (only available if coinstatsindex is used)", + { + {RPCResult::Type::STR_AMOUNT, "prevout_spent", "Total amount of all prevouts spent in this block"}, + {RPCResult::Type::STR_AMOUNT, "coinbase", "Coinbase subsidy amount of this block"}, + {RPCResult::Type::STR_AMOUNT, "new_outputs_ex_coinbase", "Total amount of new outputs created by this block"}, + {RPCResult::Type::STR_AMOUNT, "unspendable", "Total amount of unspendable outputs created in this block"}, + {RPCResult::Type::OBJ, "unspendables", "Detailed view of the unspendable categories", + { + {RPCResult::Type::STR_AMOUNT, "genesis_block", "The unspendable amount of the Genesis block subsidy"}, + {RPCResult::Type::STR_AMOUNT, "bip30", "Transactions overridden by duplicates (no longer possible with BIP30)"}, + {RPCResult::Type::STR_AMOUNT, "scripts", "Amounts sent to scripts that are unspendable (for example OP_RETURN outputs)"}, + {RPCResult::Type::STR_AMOUNT, "unclaimed_rewards", "Fee rewards that miners did not claim in their coinbase transaction"}, + }} + }}, + }}, + RPCExamples{ + HelpExampleCli("gettxoutsetinfo", "") + + HelpExampleCli("gettxoutsetinfo", R"("none")") + + HelpExampleCli("gettxoutsetinfo", R"("none" 1000)") + + HelpExampleCli("gettxoutsetinfo", R"("none" '"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09"')") + + HelpExampleCli("-named gettxoutsetinfo", R"(hash_type='muhash' use_index='false')") + + HelpExampleRpc("gettxoutsetinfo", "") + + HelpExampleRpc("gettxoutsetinfo", R"("none")") + + HelpExampleRpc("gettxoutsetinfo", R"("none", 1000)") + + HelpExampleRpc("gettxoutsetinfo", R"("none", "00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09")") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { UniValue ret(UniValue::VOBJ); @@ -1304,25 +1304,24 @@ static RPCHelpMan gettxout() {RPCResult::Type::STR_HEX, "bestblock", "The hash of the block at the tip of the chain"}, {RPCResult::Type::NUM, "confirmations", "The number of confirmations"}, {RPCResult::Type::STR_AMOUNT, "value", "The transaction value in " + CURRENCY_UNIT}, - {RPCResult::Type::OBJ, "scriptPubKey", "", - { - {RPCResult::Type::STR, "asm", "Disassembly of the public key script"}, - {RPCResult::Type::STR, "desc", "Inferred descriptor for the output"}, - {RPCResult::Type::STR_HEX, "hex", "The raw public key script bytes, hex-encoded"}, - {RPCResult::Type::STR_HEX, "type", "The type, eg pubkeyhash"}, - {RPCResult::Type::STR, "address", /*optional=*/ true, "Dash address (only if a well-defined address exists)"}, - }}, + {RPCResult::Type::OBJ, "scriptPubKey", "", { + {RPCResult::Type::STR, "asm", "Disassembly of the public key script"}, + {RPCResult::Type::STR, "desc", "Inferred descriptor for the output"}, + {RPCResult::Type::STR_HEX, "hex", "The raw public key script bytes, hex-encoded"}, + {RPCResult::Type::STR_HEX, "type", "The type, eg pubkeyhash"}, + {RPCResult::Type::STR, "address", /*optional=*/ true, "Dash address (only if a well-defined address exists)"}, + }}, {RPCResult::Type::BOOL, "coinbase", "Coinbase or not"}, }}, }, RPCExamples{ - "\nGet unspent transactions\n" - + HelpExampleCli("listunspent", "") + - "\nView the details\n" - + HelpExampleCli("gettxout", "\"txid\" 1") + - "\nAs a JSON-RPC call\n" - + HelpExampleRpc("gettxout", "\"txid\", 1") - }, + "\nGet unspent transactions\n" + + HelpExampleCli("listunspent", "") + + "\nView the details\n" + + HelpExampleCli("gettxout", "\"txid\" 1") + + "\nAs a JSON-RPC call\n" + + HelpExampleRpc("gettxout", "\"txid\", 1") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { @@ -1378,18 +1377,18 @@ static RPCHelpMan gettxout() static RPCHelpMan verifychain() { return RPCHelpMan{"verifychain", - "\nVerifies blockchain database.\n", - { - {"checklevel", RPCArg::Type::NUM, RPCArg::DefaultHint{strprintf("%d, range=0-4", DEFAULT_CHECKLEVEL)}, + "\nVerifies blockchain database.\n", + { + {"checklevel", RPCArg::Type::NUM, RPCArg::DefaultHint{strprintf("%d, range=0-4", DEFAULT_CHECKLEVEL)}, strprintf("How thorough the block verification is:\n - %s", MakeUnorderedList(CHECKLEVEL_DOC))}, - {"nblocks", RPCArg::Type::NUM, RPCArg::DefaultHint{strprintf("%d, 0=all", DEFAULT_CHECKBLOCKS)}, "The number of blocks to check."}, - }, - RPCResult{ - RPCResult::Type::BOOL, "", "Verified or not"}, - RPCExamples{ - HelpExampleCli("verifychain", "") - + HelpExampleRpc("verifychain", "") - }, + {"nblocks", RPCArg::Type::NUM, RPCArg::DefaultHint{strprintf("%d, 0=all", DEFAULT_CHECKBLOCKS)}, "The number of blocks to check."}, + }, + RPCResult{ + RPCResult::Type::BOOL, "", "Verified or not"}, + RPCExamples{ + HelpExampleCli("verifychain", "") + + HelpExampleRpc("verifychain", "") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { const int check_level{request.params[0].isNull() ? DEFAULT_CHECKLEVEL : request.params[0].getInt()}; @@ -1631,35 +1630,35 @@ struct CompareBlocksByHeight static 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", - { - {"count", RPCArg::Type::NUM, RPCArg::Default{INT_MAX}, "only show this much of latest tips"}, - {"branchlen", RPCArg::Type::NUM, RPCArg::Default{-1}, "only show tips that have equal or greater length of branch"}, - }, - RPCResult{ - RPCResult::Type::ARR, "", "", - {{RPCResult::Type::OBJ, "", "", + "Return information about all known tips in the block tree," + " including the main chain as well as orphaned branches.\n", { - {RPCResult::Type::NUM, "height", "height of the chain tip"}, - {RPCResult::Type::STR_HEX, "hash", "block hash of the tip"}, - {RPCResult::Type::NUM, "difficulty", "The difficulty"}, - {RPCResult::Type::STR_HEX, "chainwork", "Expected number of hashes required to produce the current chain (in hex)"}, - {RPCResult::Type::NUM, "branchlen", "zero for main chain, otherwise length of branch connecting the tip to the main chain"}, - {RPCResult::Type::STR_HEX, "forkpoint", "same as \"hash\" for the main chain"}, - {RPCResult::Type::STR, "status", "status of the chain, \"active\" for the main chain\n" - "Possible values for status:\n" - "1. \"invalid\" This branch contains at least one invalid block\n" - "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n" - "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n" - "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n" - "5. \"active\" This is the tip of the active main chain, which is certainly valid\n" - "6. \"conflicting\" This block or one of its ancestors is conflicting with ChainLocks."}, - }}}}, - RPCExamples{ - HelpExampleCli("getchaintips", "") - + HelpExampleRpc("getchaintips", "") - }, + {"count", RPCArg::Type::NUM, RPCArg::Default{INT_MAX}, "only show this much of latest tips"}, + {"branchlen", RPCArg::Type::NUM, RPCArg::Default{-1}, "only show tips that have equal or greater length of branch"}, + }, + RPCResult{ + RPCResult::Type::ARR, "", "", + {{RPCResult::Type::OBJ, "", "", + { + {RPCResult::Type::NUM, "height", "height of the chain tip"}, + {RPCResult::Type::STR_HEX, "hash", "block hash of the tip"}, + {RPCResult::Type::NUM, "difficulty", "The difficulty"}, + {RPCResult::Type::STR_HEX, "chainwork", "Expected number of hashes required to produce the current chain (in hex)"}, + {RPCResult::Type::NUM, "branchlen", "zero for main chain, otherwise length of branch connecting the tip to the main chain"}, + {RPCResult::Type::STR_HEX, "forkpoint", "same as \"hash\" for the main chain"}, + {RPCResult::Type::STR, "status", "status of the chain, \"active\" for the main chain\n" + "Possible values for status:\n" + "1. \"invalid\" This branch contains at least one invalid block\n" + "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n" + "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n" + "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n" + "5. \"active\" This is the tip of the active main chain, which is certainly valid\n" + "6. \"conflicting\" This block or one of its ancestors is conflicting with ChainLocks."}, + }}}}, + RPCExamples{ + HelpExampleCli("getchaintips", "") + + HelpExampleRpc("getchaintips", "") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { @@ -1751,17 +1750,17 @@ static RPCHelpMan getchaintips() static 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", - { - {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hash of the block to mark as precious"}, - }, - RPCResult{RPCResult::Type::NONE, "", ""}, - RPCExamples{ - HelpExampleCli("preciousblock", "\"blockhash\"") - + HelpExampleRpc("preciousblock", "\"blockhash\"") - }, + "\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, RPCArg::Optional::NO, "the hash of the block to mark as precious"}, + }, + RPCResult{RPCResult::Type::NONE, "", ""}, + RPCExamples{ + HelpExampleCli("preciousblock", "\"blockhash\"") + + HelpExampleRpc("preciousblock", "\"blockhash\"") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { uint256 hash(ParseHashV(request.params[0], "blockhash")); @@ -1791,15 +1790,15 @@ static RPCHelpMan preciousblock() static 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"}, - }, - RPCResult{RPCResult::Type::NONE, "", ""}, - RPCExamples{ - HelpExampleCli("invalidateblock", "\"blockhash\"") - + HelpExampleRpc("invalidateblock", "\"blockhash\"") - }, + "\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"}, + }, + RPCResult{RPCResult::Type::NONE, "", ""}, + RPCExamples{ + HelpExampleCli("invalidateblock", "\"blockhash\"") + + HelpExampleRpc("invalidateblock", "\"blockhash\"") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { uint256 hash(ParseHashV(request.params[0], "blockhash")); @@ -1834,17 +1833,17 @@ static RPCHelpMan invalidateblock() static 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", - { - {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hash of the block to reconsider"}, - {"ignore_chainlocks", RPCArg::Type::BOOL, RPCArg::Default{false}, "if true, existing chainlocks will be ignored"}, - }, - RPCResult{RPCResult::Type::NONE, "", ""}, - RPCExamples{ - HelpExampleCli("reconsiderblock", "\"blockhash\"") - + HelpExampleRpc("reconsiderblock", "\"blockhash\"") - }, + "\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", + { + {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hash of the block to reconsider"}, + {"ignore_chainlocks", RPCArg::Type::BOOL, RPCArg::Default{false}, "if true, existing chainlocks will be ignored"}, + }, + RPCResult{RPCResult::Type::NONE, "", ""}, + RPCExamples{ + HelpExampleCli("reconsiderblock", "\"blockhash\"") + + HelpExampleRpc("reconsiderblock", "\"blockhash\"") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { ChainstateManager& chainman = EnsureAnyChainman(request.context); @@ -2466,18 +2465,18 @@ static RPCHelpMan scantxoutset() {RPCResult::Type::NUM, "height", "The current block height (index)"}, {RPCResult::Type::STR_HEX, "bestblock", "The hash of the block at the tip of the chain"}, {RPCResult::Type::ARR, "unspents", "", + { + {RPCResult::Type::OBJ, "", "", { - {RPCResult::Type::OBJ, "", "", - { - {RPCResult::Type::STR_HEX, "txid", "The transaction id"}, - {RPCResult::Type::NUM, "vout", "The vout value"}, - {RPCResult::Type::STR_HEX, "scriptPubKey", "The script key"}, - {RPCResult::Type::STR, "desc", "A specialized descriptor for the matched scriptPubKey"}, - {RPCResult::Type::STR_AMOUNT, "amount", "The total amount in " + CURRENCY_UNIT + " of the unspent output"}, - {RPCResult::Type::BOOL, "coinbase", "Whether this is a coinbase output"}, - {RPCResult::Type::NUM, "height", "Height of the unspent transaction output"}, - }}, + {RPCResult::Type::STR_HEX, "txid", "The transaction id"}, + {RPCResult::Type::NUM, "vout", "The vout value"}, + {RPCResult::Type::STR_HEX, "scriptPubKey", "The script key"}, + {RPCResult::Type::STR, "desc", "A specialized descriptor for the matched scriptPubKey"}, + {RPCResult::Type::STR_AMOUNT, "amount", "The total amount in " + CURRENCY_UNIT + " of the unspent output"}, + {RPCResult::Type::BOOL, "coinbase", "Whether this is a coinbase output"}, + {RPCResult::Type::NUM, "height", "Height of the unspent transaction output"}, }}, + }}, {RPCResult::Type::STR_AMOUNT, "total_amount", "The total amount of all found unspent outputs in " + CURRENCY_UNIT}, }}, RPCResult{"when action=='abort'", RPCResult::Type::BOOL, "success", "True if scan will be aborted (not necessarily before this RPC returns), or false if there is no scan to abort"}, @@ -2596,21 +2595,21 @@ static RPCHelpMan scantxoutset() static 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"}, - {"filtertype", RPCArg::Type::STR, RPCArg::Default{BlockFilterTypeName(BlockFilterType::BASIC_FILTER)}, "The type name of the filter"}, - }, - RPCResult{ - RPCResult::Type::OBJ, "", "", - { - {RPCResult::Type::STR_HEX, "filter", "the hex-encoded filter data"}, - {RPCResult::Type::STR_HEX, "header", "the hex-encoded filter header"}, - }}, - RPCExamples{ - HelpExampleCli("getblockfilter", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\" \"basic\"")+ - HelpExampleRpc("getblockfilter", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\", \"basic\"") - }, + "\nRetrieve a BIP 157 content filter for a particular block.\n", + { + {"blockhash", RPCArg::Type::STR, RPCArg::Optional::NO, "The hash of the block"}, + {"filtertype", RPCArg::Type::STR, RPCArg::Default{BlockFilterTypeName(BlockFilterType::BASIC_FILTER)}, "The type name of the filter"}, + }, + RPCResult{ + RPCResult::Type::OBJ, "", "", + { + {RPCResult::Type::STR_HEX, "filter", "the hex-encoded filter data"}, + {RPCResult::Type::STR_HEX, "header", "the hex-encoded filter header"}, + }}, + RPCExamples{ + HelpExampleCli("getblockfilter", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\" \"basic\"")+ + HelpExampleRpc("getblockfilter", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\", \"basic\"") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { uint256 block_hash(ParseHashV(request.params[0], "blockhash")); diff --git a/src/rpc/fees.cpp b/src/rpc/fees.cpp index 8a4030f9a15f..0835759b3e75 100644 --- a/src/rpc/fees.cpp +++ b/src/rpc/fees.cpp @@ -63,40 +63,40 @@ static RPCHelpMan estimatesmartfee() HelpExampleRpc("estimatesmartfee", "6") }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue -{ - RPCTypeCheck(request.params, {UniValue::VNUM, UniValue::VSTR}); - - CBlockPolicyEstimator& fee_estimator = EnsureAnyFeeEstimator(request.context); - const NodeContext& node = EnsureAnyNodeContext(request.context); - const CTxMemPool& mempool = EnsureMemPool(node); - - unsigned int max_target = fee_estimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE); - unsigned int conf_target = ParseConfirmTarget(request.params[0], max_target); - bool conservative = true; - if (!request.params[1].isNull()) { - FeeEstimateMode fee_mode; - if (!FeeModeFromString(request.params[1].get_str(), fee_mode)) { - throw JSONRPCError(RPC_INVALID_PARAMETER, InvalidEstimateModeErrorMessage()); - } - if (fee_mode == FeeEstimateMode::ECONOMICAL) conservative = false; - } - - UniValue result(UniValue::VOBJ); - UniValue errors(UniValue::VARR); - FeeCalculation feeCalc; - CFeeRate feeRate{fee_estimator.estimateSmartFee(conf_target, &feeCalc, conservative)}; - if (feeRate != CFeeRate(0)) { - CFeeRate min_mempool_feerate{mempool.GetMinFee(gArgs.GetIntArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000)}; - CFeeRate min_relay_feerate{::minRelayTxFee}; - feeRate = std::max({feeRate, min_mempool_feerate, min_relay_feerate}); - result.pushKV("feerate", ValueFromAmount(feeRate.GetFeePerK())); - } else { - errors.push_back("Insufficient data or no feerate found"); - result.pushKV("errors", errors); - } - result.pushKV("blocks", feeCalc.returnedTarget); - return result; -}, + { + RPCTypeCheck(request.params, {UniValue::VNUM, UniValue::VSTR}); + + CBlockPolicyEstimator& fee_estimator = EnsureAnyFeeEstimator(request.context); + const NodeContext& node = EnsureAnyNodeContext(request.context); + const CTxMemPool& mempool = EnsureMemPool(node); + + unsigned int max_target = fee_estimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE); + unsigned int conf_target = ParseConfirmTarget(request.params[0], max_target); + bool conservative = true; + if (!request.params[1].isNull()) { + FeeEstimateMode fee_mode; + if (!FeeModeFromString(request.params[1].get_str(), fee_mode)) { + throw JSONRPCError(RPC_INVALID_PARAMETER, InvalidEstimateModeErrorMessage()); + } + if (fee_mode == FeeEstimateMode::ECONOMICAL) conservative = false; + } + + UniValue result(UniValue::VOBJ); + UniValue errors(UniValue::VARR); + FeeCalculation feeCalc; + CFeeRate feeRate{fee_estimator.estimateSmartFee(conf_target, &feeCalc, conservative)}; + if (feeRate != CFeeRate(0)) { + CFeeRate min_mempool_feerate{mempool.GetMinFee(gArgs.GetIntArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000)}; + CFeeRate min_relay_feerate{::minRelayTxFee}; + feeRate = std::max({feeRate, min_mempool_feerate, min_relay_feerate}); + result.pushKV("feerate", ValueFromAmount(feeRate.GetFeePerK())); + } else { + errors.push_back("Insufficient data or no feerate found"); + result.pushKV("errors", errors); + } + result.pushKV("blocks", feeCalc.returnedTarget); + return result; + }, }; } @@ -154,68 +154,68 @@ static RPCHelpMan estimaterawfee() HelpExampleCli("estimaterawfee", "6 0.9") }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue -{ - RPCTypeCheck(request.params, {UniValue::VNUM, UniValue::VNUM}, true); - - CBlockPolicyEstimator& fee_estimator = EnsureAnyFeeEstimator(request.context); - - unsigned int max_target = fee_estimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE); - unsigned int conf_target = ParseConfirmTarget(request.params[0], max_target); - double threshold = 0.95; - if (!request.params[1].isNull()) { - threshold = request.params[1].get_real(); - } - if (threshold < 0 || threshold > 1) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid threshold"); - } - - UniValue result(UniValue::VOBJ); - - for (const FeeEstimateHorizon horizon : ALL_FEE_ESTIMATE_HORIZONS) { - CFeeRate feeRate; - EstimationResult buckets; - - // Only output results for horizons which track the target - if (conf_target > fee_estimator.HighestTargetTracked(horizon)) continue; - - feeRate = fee_estimator.estimateRawFee(conf_target, threshold, horizon, &buckets); - UniValue horizon_result(UniValue::VOBJ); - UniValue errors(UniValue::VARR); - UniValue passbucket(UniValue::VOBJ); - passbucket.pushKV("startrange", round(buckets.pass.start)); - passbucket.pushKV("endrange", round(buckets.pass.end)); - passbucket.pushKV("withintarget", round(buckets.pass.withinTarget * 100.0) / 100.0); - passbucket.pushKV("totalconfirmed", round(buckets.pass.totalConfirmed * 100.0) / 100.0); - passbucket.pushKV("inmempool", round(buckets.pass.inMempool * 100.0) / 100.0); - passbucket.pushKV("leftmempool", round(buckets.pass.leftMempool * 100.0) / 100.0); - UniValue failbucket(UniValue::VOBJ); - failbucket.pushKV("startrange", round(buckets.fail.start)); - failbucket.pushKV("endrange", round(buckets.fail.end)); - failbucket.pushKV("withintarget", round(buckets.fail.withinTarget * 100.0) / 100.0); - failbucket.pushKV("totalconfirmed", round(buckets.fail.totalConfirmed * 100.0) / 100.0); - failbucket.pushKV("inmempool", round(buckets.fail.inMempool * 100.0) / 100.0); - failbucket.pushKV("leftmempool", round(buckets.fail.leftMempool * 100.0) / 100.0); - - // CFeeRate(0) is used to indicate error as a return value from estimateRawFee - if (feeRate != CFeeRate(0)) { - horizon_result.pushKV("feerate", ValueFromAmount(feeRate.GetFeePerK())); - horizon_result.pushKV("decay", buckets.decay); - horizon_result.pushKV("scale", (int)buckets.scale); - horizon_result.pushKV("pass", passbucket); - // buckets.fail.start == -1 indicates that all buckets passed, there is no fail bucket to output - if (buckets.fail.start != -1) horizon_result.pushKV("fail", failbucket); - } else { - // Output only information that is still meaningful in the event of error - horizon_result.pushKV("decay", buckets.decay); - horizon_result.pushKV("scale", (int)buckets.scale); - horizon_result.pushKV("fail", failbucket); - errors.push_back("Insufficient data or no feerate found which meets threshold"); - horizon_result.pushKV("errors", errors); - } - result.pushKV(StringForFeeEstimateHorizon(horizon), horizon_result); - } - return result; -}, + { + RPCTypeCheck(request.params, {UniValue::VNUM, UniValue::VNUM}, true); + + CBlockPolicyEstimator& fee_estimator = EnsureAnyFeeEstimator(request.context); + + unsigned int max_target = fee_estimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE); + unsigned int conf_target = ParseConfirmTarget(request.params[0], max_target); + double threshold = 0.95; + if (!request.params[1].isNull()) { + threshold = request.params[1].get_real(); + } + if (threshold < 0 || threshold > 1) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid threshold"); + } + + UniValue result(UniValue::VOBJ); + + for (const FeeEstimateHorizon horizon : ALL_FEE_ESTIMATE_HORIZONS) { + CFeeRate feeRate; + EstimationResult buckets; + + // Only output results for horizons which track the target + if (conf_target > fee_estimator.HighestTargetTracked(horizon)) continue; + + feeRate = fee_estimator.estimateRawFee(conf_target, threshold, horizon, &buckets); + UniValue horizon_result(UniValue::VOBJ); + UniValue errors(UniValue::VARR); + UniValue passbucket(UniValue::VOBJ); + passbucket.pushKV("startrange", round(buckets.pass.start)); + passbucket.pushKV("endrange", round(buckets.pass.end)); + passbucket.pushKV("withintarget", round(buckets.pass.withinTarget * 100.0) / 100.0); + passbucket.pushKV("totalconfirmed", round(buckets.pass.totalConfirmed * 100.0) / 100.0); + passbucket.pushKV("inmempool", round(buckets.pass.inMempool * 100.0) / 100.0); + passbucket.pushKV("leftmempool", round(buckets.pass.leftMempool * 100.0) / 100.0); + UniValue failbucket(UniValue::VOBJ); + failbucket.pushKV("startrange", round(buckets.fail.start)); + failbucket.pushKV("endrange", round(buckets.fail.end)); + failbucket.pushKV("withintarget", round(buckets.fail.withinTarget * 100.0) / 100.0); + failbucket.pushKV("totalconfirmed", round(buckets.fail.totalConfirmed * 100.0) / 100.0); + failbucket.pushKV("inmempool", round(buckets.fail.inMempool * 100.0) / 100.0); + failbucket.pushKV("leftmempool", round(buckets.fail.leftMempool * 100.0) / 100.0); + + // CFeeRate(0) is used to indicate error as a return value from estimateRawFee + if (feeRate != CFeeRate(0)) { + horizon_result.pushKV("feerate", ValueFromAmount(feeRate.GetFeePerK())); + horizon_result.pushKV("decay", buckets.decay); + horizon_result.pushKV("scale", (int)buckets.scale); + horizon_result.pushKV("pass", passbucket); + // buckets.fail.start == -1 indicates that all buckets passed, there is no fail bucket to output + if (buckets.fail.start != -1) horizon_result.pushKV("fail", failbucket); + } else { + // Output only information that is still meaningful in the event of error + horizon_result.pushKV("decay", buckets.decay); + horizon_result.pushKV("scale", (int)buckets.scale); + horizon_result.pushKV("fail", failbucket); + errors.push_back("Insufficient data or no feerate found which meets threshold"); + horizon_result.pushKV("errors", errors); + } + result.pushKV(StringForFeeEstimateHorizon(horizon), horizon_result); + } + return result; + }, }; } diff --git a/src/rpc/mempool.cpp b/src/rpc/mempool.cpp index adaf7eee581a..09d617f26411 100644 --- a/src/rpc/mempool.cpp +++ b/src/rpc/mempool.cpp @@ -236,37 +236,37 @@ static RPCHelpMan testmempoolaccept() static std::vector MempoolEntryDescription() { return { - RPCResult{RPCResult::Type::NUM, "vsize", "virtual transaction size. This can be different from actual serialized size for high-sigop transactions."}, - RPCResult{RPCResult::Type::STR_AMOUNT, "fee", /*optional=*/true, - "transaction fee, denominated in " + CURRENCY_UNIT + " (DEPRECATED, returned only if config option -deprecatedrpc=fees is passed)"}, - RPCResult{RPCResult::Type::STR_AMOUNT, "modifiedfee", /*optional=*/true, - "transaction fee with fee deltas used for mining priority, denominated in " + CURRENCY_UNIT + - " (DEPRECATED, returned only if config option -deprecatedrpc=fees is passed)"}, - RPCResult{RPCResult::Type::NUM_TIME, "time", "local time transaction entered pool in " + UNIX_EPOCH_TIME}, - RPCResult{RPCResult::Type::NUM, "height", "block height when transaction entered pool"}, - RPCResult{RPCResult::Type::NUM, "descendantcount", "number of in-mempool descendant transactions (including this one)"}, - RPCResult{RPCResult::Type::NUM, "descendantsize", "size of in-mempool descendants (including this one)"}, - RPCResult{RPCResult::Type::STR_AMOUNT, "descendantfees", /*optional=*/true, - "transaction fees of in-mempool descendants (including this one) with fee deltas used for mining priority, denominated in " + - CURRENCY_ATOM + "s (DEPRECATED, returned only if config option -deprecatedrpc=fees is passed)"}, - RPCResult{RPCResult::Type::NUM, "ancestorcount", "number of in-mempool ancestor transactions (including this one)"}, - RPCResult{RPCResult::Type::NUM, "ancestorsize", "size of in-mempool ancestors (including this one)"}, - RPCResult{RPCResult::Type::STR_AMOUNT, "ancestorfees", /*optional=*/true, - "transaction fees of in-mempool ancestors (including this one) with fee deltas used for mining priority, denominated in " + - CURRENCY_ATOM + "s (DEPRECATED, returned only if config option -deprecatedrpc=fees is passed)"}, - RPCResult{RPCResult::Type::OBJ, "fees", "", - { - RPCResult{RPCResult::Type::STR_AMOUNT, "base", "transaction fee, denominated in " + CURRENCY_UNIT}, - RPCResult{RPCResult::Type::STR_AMOUNT, "modified", "transaction fee with fee deltas used for mining priority, denominated in " + CURRENCY_UNIT}, - RPCResult{RPCResult::Type::STR_AMOUNT, "ancestor", "transaction fees of in-mempool ancestors (including this one) with fee deltas used for mining priority, denominated in " + CURRENCY_UNIT}, - RPCResult{RPCResult::Type::STR_AMOUNT, "descendant", "transaction fees of in-mempool descendants (including this one) with fee deltas used for mining priority, denominated in " + CURRENCY_UNIT}, - }}, - RPCResult{RPCResult::Type::ARR, "depends", "unconfirmed transactions used as inputs for this transaction", - {RPCResult{RPCResult::Type::STR_HEX, "transactionid", "parent transaction id"}}}, - RPCResult{RPCResult::Type::ARR, "spentby", "unconfirmed transactions spending outputs from this transaction", - {RPCResult{RPCResult::Type::STR_HEX, "transactionid", "child transaction id"}}}, - RPCResult{RPCResult::Type::BOOL, "instantsend", "True if this transaction was locked via InstantSend"}, - RPCResult{RPCResult::Type::BOOL, "unbroadcast", "Whether this transaction is currently unbroadcast (initial broadcast not yet acknowledged by any peers)"} + RPCResult{RPCResult::Type::NUM, "vsize", "virtual transaction size. This can be different from actual serialized size for high-sigop transactions."}, + RPCResult{RPCResult::Type::STR_AMOUNT, "fee", /*optional=*/true, + "transaction fee, denominated in " + CURRENCY_UNIT + " (DEPRECATED, returned only if config option -deprecatedrpc=fees is passed)"}, + RPCResult{RPCResult::Type::STR_AMOUNT, "modifiedfee", /*optional=*/true, + "transaction fee with fee deltas used for mining priority, denominated in " + CURRENCY_UNIT + + " (DEPRECATED, returned only if config option -deprecatedrpc=fees is passed)"}, + RPCResult{RPCResult::Type::NUM_TIME, "time", "local time transaction entered pool in " + UNIX_EPOCH_TIME}, + RPCResult{RPCResult::Type::NUM, "height", "block height when transaction entered pool"}, + RPCResult{RPCResult::Type::NUM, "descendantcount", "number of in-mempool descendant transactions (including this one)"}, + RPCResult{RPCResult::Type::NUM, "descendantsize", "size of in-mempool descendants (including this one)"}, + RPCResult{RPCResult::Type::STR_AMOUNT, "descendantfees", /*optional=*/true, + "transaction fees of in-mempool descendants (including this one) with fee deltas used for mining priority, denominated in " + + CURRENCY_ATOM + "s (DEPRECATED, returned only if config option -deprecatedrpc=fees is passed)"}, + RPCResult{RPCResult::Type::NUM, "ancestorcount", "number of in-mempool ancestor transactions (including this one)"}, + RPCResult{RPCResult::Type::NUM, "ancestorsize", "size of in-mempool ancestors (including this one)"}, + RPCResult{RPCResult::Type::STR_AMOUNT, "ancestorfees", /*optional=*/true, + "transaction fees of in-mempool ancestors (including this one) with fee deltas used for mining priority, denominated in " + + CURRENCY_ATOM + "s (DEPRECATED, returned only if config option -deprecatedrpc=fees is passed)"}, + RPCResult{RPCResult::Type::OBJ, "fees", "", + { + RPCResult{RPCResult::Type::STR_AMOUNT, "base", "transaction fee, denominated in " + CURRENCY_UNIT}, + RPCResult{RPCResult::Type::STR_AMOUNT, "modified", "transaction fee with fee deltas used for mining priority, denominated in " + CURRENCY_UNIT}, + RPCResult{RPCResult::Type::STR_AMOUNT, "ancestor", "transaction fees of in-mempool ancestors (including this one) with fee deltas used for mining priority, denominated in " + CURRENCY_UNIT}, + RPCResult{RPCResult::Type::STR_AMOUNT, "descendant", "transaction fees of in-mempool descendants (including this one) with fee deltas used for mining priority, denominated in " + CURRENCY_UNIT}, + }}, + RPCResult{RPCResult::Type::ARR, "depends", "unconfirmed transactions used as inputs for this transaction", + {RPCResult{RPCResult::Type::STR_HEX, "transactionid", "parent transaction id"}}}, + RPCResult{RPCResult::Type::ARR, "spentby", "unconfirmed transactions spending outputs from this transaction", + {RPCResult{RPCResult::Type::STR_HEX, "transactionid", "child transaction id"}}}, + RPCResult{RPCResult::Type::BOOL, "instantsend", "True if this transaction was locked via InstantSend"}, + RPCResult{RPCResult::Type::BOOL, "unbroadcast", "Whether this transaction is currently unbroadcast (initial broadcast not yet acknowledged by any peers)"} }; } diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index c05badf975b8..7f871feafb61 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -101,19 +101,19 @@ static UniValue GetNetworkHashPS(int lookup, int height, const CChain& active_ch static 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", - { - {"nblocks", RPCArg::Type::NUM, RPCArg::Default{120}, "The number of blocks, or -1 for blocks since last difficulty change."}, - {"height", RPCArg::Type::NUM, RPCArg::Default{-1}, "To estimate at the time of the given height."}, - }, - RPCResult{ - RPCResult::Type::NUM, "", "Hashes per second estimated"}, - RPCExamples{ - HelpExampleCli("getnetworkhashps", "") - + HelpExampleRpc("getnetworkhashps", "") - }, + "\nReturns the estimated network hashes per second based on the last n blocks.\n" + "Pass in [blocks] to override # of blocks, -1 specifies since last difficulty change.\n" + "Pass in [height] to estimate the network speed at the time when a certain block was found.\n", + { + {"nblocks", RPCArg::Type::NUM, RPCArg::Default{120}, "The number of blocks, or -1 for blocks since last difficulty change."}, + {"height", RPCArg::Type::NUM, RPCArg::Default{-1}, "To estimate at the time of the given height."}, + }, + RPCResult{ + RPCResult::Type::NUM, "", "Hashes per second estimated"}, + RPCExamples{ + HelpExampleCli("getnetworkhashps", "") + + HelpExampleRpc("getnetworkhashps", "") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { @@ -253,21 +253,22 @@ static RPCHelpMan generatetoaddress() { return RPCHelpMan{"generatetoaddress", "\nMine to a specified address and return the block hashes.\n", - { - {"nblocks", RPCArg::Type::NUM, RPCArg::Optional::NO, "How many blocks are generated."}, - {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The address to send the newly generated coins to."}, - {"maxtries", RPCArg::Type::NUM, RPCArg::Default{DEFAULT_MAX_TRIES}, "How many iterations to try."}, - }, - RPCResult{ - RPCResult::Type::ARR, "", "hashes of blocks generated", - { - {RPCResult::Type::STR_HEX, "", "blockhash"}, - }}, - RPCExamples{ - "\nGenerate 11 blocks to myaddress\n" - + 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", "")}, + { + {"nblocks", RPCArg::Type::NUM, RPCArg::Optional::NO, "How many blocks are generated."}, + {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The address to send the newly generated coins to."}, + {"maxtries", RPCArg::Type::NUM, RPCArg::Default{DEFAULT_MAX_TRIES}, "How many iterations to try."}, + }, + RPCResult{ + RPCResult::Type::ARR, "", "hashes of blocks generated", + { + {RPCResult::Type::STR_HEX, "", "blockhash"}, + }}, + RPCExamples{ + "\nGenerate 11 blocks to myaddress\n" + + 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", "") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { const int num_blocks{request.params[0].getInt()}; @@ -575,13 +576,13 @@ static RPCHelpMan getblocktemplate() }}, {RPCResult::Type::NUM, "version", "The preferred block version"}, {RPCResult::Type::ARR, "rules", "specific block rules that are to be enforced", - { - {RPCResult::Type::STR, "", "name of a rule the client must understand to some extent; see BIP 9 for format"}, - }}, + { + {RPCResult::Type::STR, "", "name of a rule the client must understand to some extent; see BIP 9 for format"}, + }}, {RPCResult::Type::OBJ_DYN, "vbavailable", "set of pending, supported versionbit (BIP 9) softfork deployments", - { - {RPCResult::Type::NUM, "rulename", "identifies the bit number as indicating acceptance and readiness for the named softfork rule"}, - }}, + { + {RPCResult::Type::NUM, "rulename", "identifies the bit number as indicating acceptance and readiness for the named softfork rule"}, + }}, {RPCResult::Type::ARR, "capabilities", "", { {RPCResult::Type::STR, "value", "A supported feature, for example 'proposal'"}, @@ -589,20 +590,20 @@ static RPCHelpMan getblocktemplate() {RPCResult::Type::NUM, "vbrequired", "bit mask of versionbits the server requires set in submissions"}, {RPCResult::Type::STR, "previousblockhash", "The hash of current highest block"}, {RPCResult::Type::ARR, "transactions", "contents of non-coinbase transactions that should be included in the next block", + { + {RPCResult::Type::OBJ, "", "", { - {RPCResult::Type::OBJ, "", "", - { - {RPCResult::Type::STR_HEX, "data", "transaction data encoded in hexadecimal (byte-for-byte)"}, - {RPCResult::Type::STR_HEX, "txid", "transaction id encoded in little-endian hexadecimal"}, - {RPCResult::Type::STR_HEX, "hash", "hash encoded in little-endian hexadecimal"}, - {RPCResult::Type::ARR, "depends", "array of numbers", - { - {RPCResult::Type::NUM, "", "transactions before this one (by 1-based index in 'transactions' list) that must be present in the final block if this one is"}, - }}, - {RPCResult::Type::NUM, "fee", "difference in value between transaction inputs and outputs (in duffs); for coinbase transactions, this is a negative Number of the total collected block fees (ie, not including the block subsidy); if key is not present, fee is unknown and clients MUST NOT assume there isn't one"}, - {RPCResult::Type::NUM, "sigops", "total number of SigOps, as counted for purposes of block limits; if key is not present, sigop count is unknown and clients MUST NOT assume there aren't any"}, - }}, + {RPCResult::Type::STR_HEX, "data", "transaction data encoded in hexadecimal (byte-for-byte)"}, + {RPCResult::Type::STR_HEX, "txid", "transaction id encoded in little-endian hexadecimal"}, + {RPCResult::Type::STR_HEX, "hash", "hash encoded in little-endian hexadecimal"}, + {RPCResult::Type::ARR, "depends", "array of numbers", + { + {RPCResult::Type::NUM, "", "transactions before this one (by 1-based index in 'transactions' list) that must be present in the final block if this one is"}, + }}, + {RPCResult::Type::NUM, "fee", "difference in value between transaction inputs and outputs (in duffs); for coinbase transactions, this is a negative Number of the total collected block fees (ie, not including the block subsidy); if key is not present, fee is unknown and clients MUST NOT assume there isn't one"}, + {RPCResult::Type::NUM, "sigops", "total number of SigOps, as counted for purposes of block limits; if key is not present, sigop count is unknown and clients MUST NOT assume there aren't any"}, }}, + }}, {RPCResult::Type::OBJ_DYN, "coinbaseaux", "data that should be included in the coinbase's scriptSig content", { {RPCResult::Type::STR_HEX, "key", "values must be in the coinbase (keys may be ignored)"}, @@ -612,9 +613,9 @@ static RPCHelpMan getblocktemplate() {RPCResult::Type::STR, "target", "The hash target"}, {RPCResult::Type::NUM_TIME, "mintime", "The minimum timestamp appropriate for the next block time, expressed in " + UNIX_EPOCH_TIME}, {RPCResult::Type::ARR, "mutable", "list of ways the block template may be changed", - { - {RPCResult::Type::STR, "value", "A way the block template may be changed, e.g. 'time', 'transactions', 'prevblock'"}, - }}, + { + {RPCResult::Type::STR, "value", "A way the block template may be changed, e.g. 'time', 'transactions', 'prevblock'"}, + }}, {RPCResult::Type::STR_HEX, "noncerange", "A range of valid nonces"}, {RPCResult::Type::NUM, "sigoplimit", "limit of sigops in blocks"}, {RPCResult::Type::NUM, "sizelimit", "limit of block size"}, @@ -1053,17 +1054,17 @@ static RPCHelpMan submitblock() static 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", - { - {"hexdata", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hex-encoded block header data"}, - }, - RPCResult{ - RPCResult::Type::NONE, "", "None"}, - RPCExamples{ - HelpExampleCli("submitheader", "\"aabbcc\"") + - HelpExampleRpc("submitheader", "\"aabbcc\"") - }, + "\nDecode the given hexdata as a header and submit it as a candidate chain tip if valid." + "\nThrows when the header is invalid.\n", + { + {"hexdata", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hex-encoded block header data"}, + }, + RPCResult{ + RPCResult::Type::NONE, "", "None"}, + RPCExamples{ + HelpExampleCli("submitheader", "\"aabbcc\"") + + HelpExampleRpc("submitheader", "\"aabbcc\"") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { CBlockHeader h; diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 3ed094b36029..a5e8cb5fdc34 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -52,15 +52,15 @@ const std::vector TRANSPORT_TYPE_DOC{ static RPCHelpMan getconnectioncount() { return RPCHelpMan{"getconnectioncount", - "\nReturns the number of connections to other nodes.\n", - {}, - RPCResult{ - RPCResult::Type::NUM, "", "The connection count" - }, - RPCExamples{ - HelpExampleCli("getconnectioncount", "") - + HelpExampleRpc("getconnectioncount", "") - }, + "\nReturns the number of connections to other nodes.\n", + {}, + RPCResult{ + RPCResult::Type::NUM, "", "The connection count" + }, + RPCExamples{ + HelpExampleCli("getconnectioncount", "") + + HelpExampleRpc("getconnectioncount", "") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { const NodeContext& node = EnsureAnyNodeContext(request.context); @@ -74,15 +74,15 @@ static RPCHelpMan getconnectioncount() static 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", - {}, - RPCResult{RPCResult::Type::NONE, "", ""}, - RPCExamples{ - HelpExampleCli("ping", "") - + HelpExampleRpc("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", + {}, + RPCResult{RPCResult::Type::NONE, "", ""}, + RPCExamples{ + HelpExampleCli("ping", "") + + HelpExampleRpc("ping", "") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { const NodeContext& node = EnsureAnyNodeContext(request.context); @@ -303,22 +303,22 @@ static RPCHelpMan getpeerinfo() static 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" - "full nodes as other outbound peers are (though such peers will not be synced from).\n" + + "\nAttempts to add or remove a node from the addnode list.\n" + "Or try a connection to a node once.\n" + "Nodes added using addnode (or -connect) are protected from DoS disconnection and are not required to be\n" + "full nodes as other outbound peers are (though such peers will not be synced from).\n" + strprintf("Addnode connections are limited to %u at a time", MAX_ADDNODE_CONNECTIONS) + " and are counted separately from the -maxconnections limit.\n", - { - {"node", RPCArg::Type::STR, RPCArg::Optional::NO, "The address of the peer to connect to"}, - {"command", RPCArg::Type::STR, RPCArg::Optional::NO, "'add' to add a node to the list, 'remove' to remove a node from the list, 'onetry' to try a connection to the node once"}, - {"v2transport", RPCArg::Type::BOOL, RPCArg::DefaultHint{"set by -v2transport"}, "Attempt to connect using BIP324 v2 transport protocol (ignored for 'remove' command)"}, - }, - RPCResult{RPCResult::Type::NONE, "", ""}, - RPCExamples{ - HelpExampleCli("addnode", "\"192.168.0.6:9999\" \"onetry\" true") - + HelpExampleRpc("addnode", "\"192.168.0.6:9999\", \"onetry\" true") - }, + { + {"node", RPCArg::Type::STR, RPCArg::Optional::NO, "The address of the peer to connect to"}, + {"command", RPCArg::Type::STR, RPCArg::Optional::NO, "'add' to add a node to the list, 'remove' to remove a node from the list, 'onetry' to try a connection to the node once"}, + {"v2transport", RPCArg::Type::BOOL, RPCArg::DefaultHint{"set by -v2transport"}, "Attempt to connect using BIP324 v2 transport protocol (ignored for 'remove' command)"}, + }, + RPCResult{RPCResult::Type::NONE, "", ""}, + RPCExamples{ + HelpExampleCli("addnode", "\"192.168.0.6:9999\" \"onetry\" true") + + HelpExampleRpc("addnode", "\"192.168.0.6:9999\", \"onetry\" true") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { const std::string command{request.params[1].get_str()}; @@ -429,20 +429,20 @@ static RPCHelpMan addconnection() static 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", - { - {"address", RPCArg::Type::STR, RPCArg::DefaultHint{"fallback to nodeid"}, "The IP address/port of the node"}, - {"nodeid", RPCArg::Type::NUM, RPCArg::DefaultHint{"fallback to address"}, "The node ID (see getpeerinfo for node IDs)"}, - }, - RPCResult{RPCResult::Type::NONE, "", ""}, - RPCExamples{ - HelpExampleCli("disconnectnode", "\"192.168.0.6:9999\"") - + HelpExampleCli("disconnectnode", "\"\" 1") - + HelpExampleRpc("disconnectnode", "\"192.168.0.6:9999\"") - + HelpExampleRpc("disconnectnode", "\"\", 1") - }, + "\nImmediately disconnects from the specified peer node.\n" + "\nStrictly one out of 'address' and 'nodeid' can be provided to identify the node.\n" + "\nTo disconnect by nodeid, either set 'address' to the empty string, or call using the named 'nodeid' argument only.\n", + { + {"address", RPCArg::Type::STR, RPCArg::DefaultHint{"fallback to nodeid"}, "The IP address/port of the node"}, + {"nodeid", RPCArg::Type::NUM, RPCArg::DefaultHint{"fallback to address"}, "The node ID (see getpeerinfo for node IDs)"}, + }, + RPCResult{RPCResult::Type::NONE, "", ""}, + RPCExamples{ + HelpExampleCli("disconnectnode", "\"192.168.0.6:9999\"") + + HelpExampleCli("disconnectnode", "\"\" 1") + + HelpExampleRpc("disconnectnode", "\"192.168.0.6:9999\"") + + HelpExampleRpc("disconnectnode", "\"\", 1") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { @@ -550,30 +550,30 @@ static RPCHelpMan getaddednodeinfo() static RPCHelpMan getnettotals() { return RPCHelpMan{"getnettotals", - "Returns information about network traffic, including bytes in, bytes out,\n" - "and current system time.", - {}, - RPCResult{ - RPCResult::Type::OBJ, "", "", - { - {RPCResult::Type::NUM, "totalbytesrecv", "Total bytes received"}, - {RPCResult::Type::NUM, "totalbytessent", "Total bytes sent"}, - {RPCResult::Type::NUM_TIME, "timemillis", "Current system " + UNIX_EPOCH_TIME + " in milliseconds"}, - {RPCResult::Type::OBJ, "uploadtarget", "", - { - {RPCResult::Type::NUM, "timeframe", "Length of the measuring timeframe in seconds"}, - {RPCResult::Type::NUM, "target", "Target in bytes"}, - {RPCResult::Type::BOOL, "target_reached", "True if target is reached"}, - {RPCResult::Type::BOOL, "serve_historical_blocks", "True if serving historical blocks"}, - {RPCResult::Type::NUM, "bytes_left_in_cycle", "Bytes left in current time cycle"}, - {RPCResult::Type::NUM, "time_left_in_cycle", "Seconds left in current time cycle"}, - }}, - } - }, - RPCExamples{ - HelpExampleCli("getnettotals", "") - + HelpExampleRpc("getnettotals", "") - }, + "Returns information about network traffic, including bytes in, bytes out,\n" + "and current system time.", + {}, + RPCResult{ + RPCResult::Type::OBJ, "", "", + { + {RPCResult::Type::NUM, "totalbytesrecv", "Total bytes received"}, + {RPCResult::Type::NUM, "totalbytessent", "Total bytes sent"}, + {RPCResult::Type::NUM_TIME, "timemillis", "Current system " + UNIX_EPOCH_TIME + " in milliseconds"}, + {RPCResult::Type::OBJ, "uploadtarget", "", + { + {RPCResult::Type::NUM, "timeframe", "Length of the measuring timeframe in seconds"}, + {RPCResult::Type::NUM, "target", "Target in bytes"}, + {RPCResult::Type::BOOL, "target_reached", "True if target is reached"}, + {RPCResult::Type::BOOL, "serve_historical_blocks", "True if serving historical blocks"}, + {RPCResult::Type::NUM, "bytes_left_in_cycle", "Bytes left in current time cycle"}, + {RPCResult::Type::NUM, "time_left_in_cycle", "Seconds left in current time cycle"}, + }}, + } + }, + RPCExamples{ + HelpExampleCli("getnettotals", "") + + HelpExampleRpc("getnettotals", "") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { const NodeContext& node = EnsureAnyNodeContext(request.context); @@ -827,10 +827,10 @@ static RPCHelpMan listbanned() {RPCResult::Type::NUM_TIME, "time_remaining", "The time remaining until the ban expires, in seconds"}, }}, }}, - RPCExamples{ - HelpExampleCli("listbanned", "") - + HelpExampleRpc("listbanned", "") - }, + RPCExamples{ + HelpExampleCli("listbanned", "") + + HelpExampleRpc("listbanned", "") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { BanMan& banman = EnsureAnyBanman(request.context); @@ -861,13 +861,13 @@ static RPCHelpMan listbanned() static RPCHelpMan clearbanned() { return RPCHelpMan{"clearbanned", - "\nClear all banned IPs.\n", - {}, - RPCResult{RPCResult::Type::NONE, "", ""}, - RPCExamples{ - HelpExampleCli("clearbanned", "") - + HelpExampleRpc("clearbanned", "") - }, + "\nClear all banned IPs.\n", + {}, + RPCResult{RPCResult::Type::NONE, "", ""}, + RPCExamples{ + HelpExampleCli("clearbanned", "") + + HelpExampleRpc("clearbanned", "") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { BanMan& banman = EnsureAnyBanman(request.context); @@ -903,12 +903,12 @@ static RPCHelpMan cleardiscouraged() static 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{""}, + "\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{""}, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { diff --git a/src/rpc/node.cpp b/src/rpc/node.cpp index b62b8b75de11..69616dd8f855 100644 --- a/src/rpc/node.cpp +++ b/src/rpc/node.cpp @@ -248,7 +248,7 @@ static RPCHelpMan setmocktime() }, RPCResult{RPCResult::Type::NONE, "", ""}, RPCExamples{""}, - [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { if (!Params().IsMockableChain()) { @@ -890,36 +890,36 @@ static RPCHelpMan getmemoryinfo() * as users will undoubtedly confuse it with the other "memory pool" */ return RPCHelpMan{"getmemoryinfo", - "Returns an object containing information about memory usage.\n", - { - {"mode", RPCArg::Type::STR, RPCArg::Default{"stats"}, "determines what kind of information is returned.\n" - " - \"stats\" returns general statistics about memory usage in the daemon.\n" - " - \"mallocinfo\" returns an XML string describing low-level heap state (only available if compiled with glibc)."}, - }, - { - RPCResult{"mode \"stats\"", - RPCResult::Type::OBJ, "", "", + "Returns an object containing information about memory usage.\n", { - {RPCResult::Type::OBJ, "locked", "Information about locked memory manager", - { - {RPCResult::Type::NUM, "used", "Number of bytes used"}, - {RPCResult::Type::NUM, "free", "Number of bytes available in current arenas"}, - {RPCResult::Type::NUM, "total", "Total number of bytes managed"}, - {RPCResult::Type::NUM, "locked", "Amount of bytes that succeeded locking. If this number is smaller than total, locking pages failed at some point and key data could be swapped to disk."}, - {RPCResult::Type::NUM, "chunks_used", "Number allocated chunks"}, - {RPCResult::Type::NUM, "chunks_free", "Number unused chunks"}, - }}, - } - }, - RPCResult{"mode \"mallocinfo\"", - RPCResult::Type::STR, "", "\"...\"" - }, - }, - RPCExamples{ - HelpExampleCli("getmemoryinfo", "") - + HelpExampleRpc("getmemoryinfo", "") - }, - [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue + {"mode", RPCArg::Type::STR, RPCArg::Default{"stats"}, "determines what kind of information is returned.\n" + " - \"stats\" returns general statistics about memory usage in the daemon.\n" + " - \"mallocinfo\" returns an XML string describing low-level heap state (only available if compiled with glibc)."}, + }, + { + RPCResult{"mode \"stats\"", + RPCResult::Type::OBJ, "", "", + { + {RPCResult::Type::OBJ, "locked", "Information about locked memory manager", + { + {RPCResult::Type::NUM, "used", "Number of bytes used"}, + {RPCResult::Type::NUM, "free", "Number of bytes available in current arenas"}, + {RPCResult::Type::NUM, "total", "Total number of bytes managed"}, + {RPCResult::Type::NUM, "locked", "Amount of bytes that succeeded locking. If this number is smaller than total, locking pages failed at some point and key data could be swapped to disk."}, + {RPCResult::Type::NUM, "chunks_used", "Number allocated chunks"}, + {RPCResult::Type::NUM, "chunks_free", "Number unused chunks"}, + }}, + } + }, + RPCResult{"mode \"mallocinfo\"", + RPCResult::Type::STR, "", "\"...\"" + }, + }, + RPCExamples{ + HelpExampleCli("getmemoryinfo", "") + + HelpExampleRpc("getmemoryinfo", "") + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { std::string mode = request.params[0].isNull() ? "stats" : request.params[0].get_str(); @@ -961,40 +961,40 @@ static void EnableOrDisableLogCategories(UniValue cats, bool enable) { static 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" - "The arguments are evaluated in order \"include\", \"exclude\".\n" - "If an item is both included and excluded, it will thus end up being excluded.\n" - "The valid logging categories are: " + LogInstance().LogCategoriesString() + "\n" - "In addition, the following are available as category names with special meanings:\n" - " - \"all\", \"1\" : represent all logging categories.\n" - " - \"dash\" activates all Dash-specific categories at once.\n" - "To deactivate all categories at once you can specify \"all\" in .\n" - " - \"none\", \"0\" : even if other logging categories are specified, ignore all of them.\n" - , - { - {"include", RPCArg::Type::ARR, RPCArg::Optional::OMITTED_NAMED_ARG, "The of categories to add to debug logging", + "Gets and sets the logging configuration.\n" + "When called without an argument, returns the list of categories with status that are currently being debug logged or not.\n" + "When called with arguments, adds or removes categories from debug logging and return the lists above.\n" + "The arguments are evaluated in order \"include\", \"exclude\".\n" + "If an item is both included and excluded, it will thus end up being excluded.\n" + "The valid logging categories are: " + LogInstance().LogCategoriesString() + "\n" + "In addition, the following are available as category names with special meanings:\n" + " - \"all\", \"1\" : represent all logging categories.\n" + " - \"dash\" activates all Dash-specific categories at once.\n" + "To deactivate all categories at once you can specify \"all\" in .\n" + " - \"none\", \"0\" : even if other logging categories are specified, ignore all of them.\n" + , { - {"include_category", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "the valid logging category"}, - }}, - {"exclude", RPCArg::Type::ARR, RPCArg::Optional::OMITTED_NAMED_ARG, "The categories to remove from debug logging", - { - {"exclude_category", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "the valid logging category"}, - }}, - }, - RPCResult{ - RPCResult::Type::OBJ_DYN, "", "keys are the logging categories, and values indicates its status", - { - {RPCResult::Type::BOOL, "category", "if being debug logged or not. false:inactive, true:active"}, + {"include", RPCArg::Type::ARR, RPCArg::Optional::OMITTED_NAMED_ARG, "The of categories to add to debug logging", + { + {"include_category", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "the valid logging category"}, + }}, + {"exclude", RPCArg::Type::ARR, RPCArg::Optional::OMITTED_NAMED_ARG, "The categories to remove from debug logging", + { + {"exclude_category", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "the valid logging category"}, + }}, + }, + RPCResult{ + RPCResult::Type::OBJ_DYN, "", "keys are the logging categories, and values indicates its status", + { + {RPCResult::Type::BOOL, "category", "if being debug logged or not. false:inactive, true:active"}, } - }, - RPCExamples{ - HelpExampleCli("logging", "\"[\\\"all\\\"]\" \"[\\\"http\\\"]\"") - + HelpExampleCli("logging", "'[\"dash\"]' '[\"llmq\",\"zmq\"]'") - + HelpExampleRpc("logging", "[\"all\"], \"[libevent]\"") - }, - [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue + }, + RPCExamples{ + HelpExampleCli("logging", "\"[\\\"all\\\"]\" \"[\\\"http\\\"]\"") + + HelpExampleCli("logging", "'[\"dash\"]' '[\"llmq\",\"zmq\"]'") + + HelpExampleRpc("logging", "[\"all\"], \"[libevent]\"") + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { uint64_t original_log_categories = LogInstance().GetCategoryMask(); @@ -1029,18 +1029,18 @@ static RPCHelpMan echo(const std::string& name) "\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, ""}, - }, + { + {"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::ANY, "", "Returns whatever was passed in"}, RPCExamples{""}, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue diff --git a/src/rpc/output_script.cpp b/src/rpc/output_script.cpp index ca5beef1d0f7..2ad98f709d38 100644 --- a/src/rpc/output_script.cpp +++ b/src/rpc/output_script.cpp @@ -46,88 +46,88 @@ static RPCHelpMan validateaddress() HelpExampleRpc("validateaddress", "\"" + EXAMPLE_ADDRESS[0] + "\"") }, [&](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); - CHECK_NONFATAL(isValid == error_msg.empty()); - - UniValue ret(UniValue::VOBJ); - ret.pushKV("isvalid", isValid); - if (isValid) { - std::string currentAddress = EncodeDestination(dest); - ret.pushKV("address", currentAddress); - - CScript scriptPubKey = GetScriptForDestination(dest); - ret.pushKV("scriptPubKey", HexStr(scriptPubKey)); - - UniValue detail = DescribeAddress(dest); - ret.pushKVs(detail); - } else { - ret.pushKV("error", error_msg); - } + { + std::string error_msg; + CTxDestination dest = DecodeDestination(request.params[0].get_str(), error_msg); + const bool isValid = IsValidDestination(dest); + CHECK_NONFATAL(isValid == error_msg.empty()); + + UniValue ret(UniValue::VOBJ); + ret.pushKV("isvalid", isValid); + if (isValid) { + std::string currentAddress = EncodeDestination(dest); + ret.pushKV("address", currentAddress); + + CScript scriptPubKey = GetScriptForDestination(dest); + ret.pushKV("scriptPubKey", HexStr(scriptPubKey)); + + UniValue detail = DescribeAddress(dest); + ret.pushKVs(detail); + } else { + ret.pushKV("error", error_msg); + } - return ret; -}, + return ret; + }, }; } static 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", + "\nCreates a multi-signature address with n signature of m keys required.\n" + "It returns a json object with the address and redeemScript.\n", + { + {"nrequired", RPCArg::Type::NUM, RPCArg::Optional::NO, "The number of required signatures out of the n keys."}, + {"keys", RPCArg::Type::ARR, RPCArg::Optional::NO, "The hex-encoded public keys.", { - {"nrequired", RPCArg::Type::NUM, RPCArg::Optional::NO, "The number of required signatures out of the n keys."}, - {"keys", RPCArg::Type::ARR, RPCArg::Optional::NO, "The hex-encoded public keys.", - { - {"key", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "The hex-encoded public key"}, - }}, - }, - RPCResult{ - RPCResult::Type::OBJ, "", "", - { - {RPCResult::Type::STR, "address", "The value of the new multisig address."}, - {RPCResult::Type::STR_HEX, "redeemScript", "The string value of the hex-encoded redemption script."}, - {RPCResult::Type::STR, "descriptor", "The descriptor for this multisig."}, - } - }, - RPCExamples{ + {"key", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "The hex-encoded public key"}, + }}, + }, + RPCResult{ + RPCResult::Type::OBJ, "", "", + { + {RPCResult::Type::STR, "address", "The value of the new multisig address."}, + {RPCResult::Type::STR_HEX, "redeemScript", "The string value of the hex-encoded redemption script."}, + {RPCResult::Type::STR, "descriptor", "The descriptor for this multisig."}, + } + }, + RPCExamples{ "\nCreate a multisig address from 2 public keys\n" + HelpExampleCli("createmultisig", "2 \"[\\\"03789ed0bb717d88f7d321a368d905e7430207ebbd82bd342cf11ae157a7ace5fd\\\",\\\"03dbc6764b8884a92e871274b87583e6d5c2a58819473e17e107ef3f6aa5a61626\\\"]\"") + "\nAs a JSON-RPC call\n" + HelpExampleRpc("createmultisig", "2, [\"03789ed0bb717d88f7d321a368d905e7430207ebbd82bd342cf11ae157a7ace5fd\",\"03dbc6764b8884a92e871274b87583e6d5c2a58819473e17e107ef3f6aa5a61626\"]") }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue -{ - int required = request.params[0].getInt(); - - // Get the public keys - const UniValue& keys = request.params[1].get_array(); - std::vector pubkeys; - for (unsigned int i = 0; i < keys.size(); ++i) { - if (IsHex(keys[i].get_str()) && (keys[i].get_str().length() == 66 || keys[i].get_str().length() == 130)) { - pubkeys.push_back(HexToPubKey(keys[i].get_str())); - } else { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Invalid public key: %s\n.", keys[i].get_str())); - } - } + { + int required = request.params[0].getInt(); + + // Get the public keys + const UniValue& keys = request.params[1].get_array(); + std::vector pubkeys; + for (unsigned int i = 0; i < keys.size(); ++i) { + if (IsHex(keys[i].get_str()) && (keys[i].get_str().length() == 66 || keys[i].get_str().length() == 130)) { + pubkeys.push_back(HexToPubKey(keys[i].get_str())); + } else { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Invalid public key: %s\n.", keys[i].get_str())); + } + } - // Construct using pay-to-script-hash: - FillableSigningProvider keystore; - CScript inner; - const CTxDestination dest = AddAndGetMultisigDestination(required, pubkeys, keystore, inner); + // Construct using pay-to-script-hash: + FillableSigningProvider keystore; + CScript inner; + const CTxDestination dest = AddAndGetMultisigDestination(required, pubkeys, keystore, inner); - // Make the descriptor - std::unique_ptr descriptor = InferDescriptor(GetScriptForDestination(dest), keystore); + // Make the descriptor + std::unique_ptr descriptor = InferDescriptor(GetScriptForDestination(dest), keystore); - UniValue result(UniValue::VOBJ); - result.pushKV("address", EncodeDestination(dest)); - result.pushKV("redeemScript", HexStr(inner)); - result.pushKV("descriptor", descriptor->ToString()); + UniValue result(UniValue::VOBJ); + result.pushKV("address", EncodeDestination(dest)); + result.pushKV("redeemScript", HexStr(inner)); + result.pushKV("descriptor", descriptor->ToString()); - return result; -}, + return result; + }, }; } @@ -142,40 +142,40 @@ static RPCHelpMan getdescriptorinfo() }, RPCResult{ RPCResult::Type::OBJ, "", "", - { + { {RPCResult::Type::STR, "descriptor", "The descriptor in canonical form, without private keys"}, {RPCResult::Type::STR, "checksum", "The checksum for the input descriptor"}, {RPCResult::Type::BOOL, "isrange", "Whether the descriptor is ranged"}, {RPCResult::Type::BOOL, "issolvable", "Whether the descriptor is solvable"}, {RPCResult::Type::BOOL, "hasprivatekeys", "Whether the input descriptor contained at least one private key"}, - } + } }, RPCExamples{ - "\nAnalyse a descriptor\n" - + HelpExampleCli("getdescriptorinfo", "\"" + EXAMPLE_DESCRIPTOR + "\"") + + "\nAnalyse a descriptor\n" + + HelpExampleCli("getdescriptorinfo", "\"" + EXAMPLE_DESCRIPTOR + "\"") + HelpExampleRpc("getdescriptorinfo", "\"" + EXAMPLE_DESCRIPTOR + "\"") }, - [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue -{ + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue + { - RPCTypeCheck(request.params, {UniValue::VSTR}); + RPCTypeCheck(request.params, {UniValue::VSTR}); - FlatSigningProvider provider; - std::string error; - auto desc = Parse(request.params[0].get_str(), provider, error); - if (!desc) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, error); - } + FlatSigningProvider provider; + std::string error; + auto desc = Parse(request.params[0].get_str(), provider, error); + if (!desc) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, error); + } - UniValue result(UniValue::VOBJ); - result.pushKV("descriptor", desc->ToString()); - result.pushKV("checksum", GetDescriptorChecksum(request.params[0].get_str())); - result.pushKV("isrange", desc->IsRange()); - result.pushKV("issolvable", desc->IsSolvable()); - result.pushKV("hasprivatekeys", provider.keys.size() > 0); - return result; -}, + UniValue result(UniValue::VOBJ); + result.pushKV("descriptor", desc->ToString()); + result.pushKV("checksum", GetDescriptorChecksum(request.params[0].get_str())); + result.pushKV("isrange", desc->IsRange()); + result.pushKV("issolvable", desc->IsSolvable()); + result.pushKV("hasprivatekeys", provider.keys.size() > 0); + return result; + }, }; } @@ -184,83 +184,83 @@ static RPCHelpMan deriveaddresses() const std::string EXAMPLE_DESCRIPTOR = "wpkh([d34db33f/84h/0h/0h]xpub6DJ2dNUysrn5Vt36jH2KLBT2i1auw1tTSSomg8PhqNiUtx8QX2SvC9nrHu81fT41fvDUnhMjEzQgXnQjKEu3oaqMSzhSrHMxyyoEAmUHQbY/0/*)#cjjspncu"; 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" - " sh(multi(,,,...)) P2SH-multisig outputs for the given threshold and pubkeys\n" - " raw() Outputs whose scriptPubKey equals the specified hex scripts\n" - "\nIn the above, either refers to a fixed public key in hexadecimal notation, or to an xpub/xprv optionally followed by one\n" - "or more path elements separated by \"/\", where \"h\" represents a hardened child key.\n" - "For more information on output descriptors, see the documentation in the doc/descriptors.md file.\n", + {"\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" + " sh(multi(,,,...)) P2SH-multisig outputs for the given threshold and pubkeys\n" + " raw() Outputs whose scriptPubKey equals the specified hex scripts\n" + "\nIn the above, either refers to a fixed public key in hexadecimal notation, or to an xpub/xprv optionally followed by one\n" + "or more path elements separated by \"/\", where \"h\" represents a hardened child key.\n" + "For more information on output descriptors, see the documentation in the doc/descriptors.md file.\n"}, + { + {"descriptor", RPCArg::Type::STR, RPCArg::Optional::NO, "The descriptor"}, + {"range", RPCArg::Type::RANGE, RPCArg::Optional::OMITTED_NAMED_ARG, "If a ranged descriptor is used, this specifies the end or the range (in [begin,end] notation) to derive."}, + }, + RPCResult{ + RPCResult::Type::ARR, "", "", { - {"descriptor", RPCArg::Type::STR, RPCArg::Optional::NO, "The descriptor"}, - {"range", RPCArg::Type::RANGE, RPCArg::Optional::OMITTED_NAMED_ARG, "If a ranged descriptor is used, this specifies the end or the range (in [begin,end] notation) to derive."}, - }, - RPCResult{ - RPCResult::Type::ARR, "", "", - { - {RPCResult::Type::STR, "address", "the derived addresses"}, - } - }, - RPCExamples{ - "\nFirst three receive addresses\n" - + HelpExampleCli("deriveaddresses", "\"" + EXAMPLE_DESCRIPTOR + "\" \"[0,2]\"") + - HelpExampleRpc("deriveaddresses", "\"" + EXAMPLE_DESCRIPTOR + "\", \"[0,2]\"") - }, - [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue -{ + {RPCResult::Type::STR, "address", "the derived addresses"}, + } + }, + RPCExamples{ + "First three receive addresses\n" + + HelpExampleCli("deriveaddresses", "\"" + EXAMPLE_DESCRIPTOR + "\" \"[0,2]\"") + + HelpExampleRpc("deriveaddresses", "\"" + EXAMPLE_DESCRIPTOR + "\", \"[0,2]\"") + }, + [&](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(); + RPCTypeCheck(request.params, {UniValue::VSTR, UniValueType()}); // Range argument is checked later + const std::string desc_str = request.params[0].get_str(); - int64_t range_begin = 0; - int64_t range_end = 0; + int64_t range_begin = 0; + int64_t range_end = 0; - if (request.params.size() >= 2 && !request.params[1].isNull()) { - std::tie(range_begin, range_end) = ParseDescriptorRange(request.params[1]); - } + if (request.params.size() >= 2 && !request.params[1].isNull()) { + std::tie(range_begin, range_end) = ParseDescriptorRange(request.params[1]); + } - FlatSigningProvider key_provider; - std::string error; - auto desc = Parse(desc_str, key_provider, error, /* require_checksum = */ true); - if (!desc) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, error); - } + FlatSigningProvider key_provider; + std::string error; + auto desc = Parse(desc_str, key_provider, error, /* require_checksum = */ true); + if (!desc) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, error); + } - if (!desc->IsRange() && request.params.size() > 1) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Range should not be specified for an un-ranged descriptor"); - } + if (!desc->IsRange() && request.params.size() > 1) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Range should not be specified for an un-ranged descriptor"); + } - if (desc->IsRange() && request.params.size() == 1) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Range must be specified for a ranged descriptor"); - } + if (desc->IsRange() && request.params.size() == 1) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Range must be specified for a ranged descriptor"); + } - UniValue addresses(UniValue::VARR); + UniValue addresses(UniValue::VARR); - for (int64_t i = range_begin; i <= range_end; ++i) { - FlatSigningProvider provider; - std::vector scripts; - if (!desc->Expand(i, key_provider, scripts, provider)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Cannot derive script without private keys"); - } + for (int64_t i = range_begin; i <= range_end; ++i) { + FlatSigningProvider provider; + std::vector scripts; + if (!desc->Expand(i, key_provider, scripts, provider)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Cannot derive script without private keys"); + } - for (const CScript &script : scripts) { - CTxDestination dest; - if (!ExtractDestination(script, dest)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Descriptor does not have a corresponding address"); - } + for (const CScript &script : scripts) { + CTxDestination dest; + if (!ExtractDestination(script, dest)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Descriptor does not have a corresponding address"); + } - addresses.push_back(EncodeDestination(dest)); - } - } + addresses.push_back(EncodeDestination(dest)); + } + } - // This should not be possible, but an assert seems overkill: - if (addresses.empty()) { - throw JSONRPCError(RPC_MISC_ERROR, "Unexpected empty result"); - } + // This should not be possible, but an assert seems overkill: + if (addresses.empty()) { + throw JSONRPCError(RPC_MISC_ERROR, "Unexpected empty result"); + } - return addresses; -}, + return addresses; + }, }; } diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 554f4bd3d53e..ed2348ebb0fc 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -223,16 +223,16 @@ static RPCHelpMan getrawtransaction() { return RPCHelpMan{ "getrawtransaction", - "Return the raw transaction data.\n" + "Return the raw transaction data.\n\n" - "\nBy default, this call only returns a transaction if it is in the mempool. If -txindex is enabled\n" + "By default, this call only returns a transaction if it is in the mempool. If -txindex is enabled\n" "and no blockhash argument is passed, it will return the transaction if it is in the mempool or any block.\n" "If a blockhash argument is passed, it will return the transaction if\n" - "the specified block is available and the transaction is in that block.\n" - "\nHint: Use gettransaction for wallet transactions.\n" + "the specified block is available and the transaction is in that block.\n\n" + "Hint: Use gettransaction for wallet transactions.\n\n" - "\nIf verbose is 'true', returns an Object with information about 'txid'.\n" - "If verbose is 'false' or omitted, returns a string that is serialized, hex-encoded data for 'txid'.", + "If verbose is 'true', returns an Object with information about 'txid'.\n\n" + "If verbose is 'false' or omitted, returns a string that is serialized, hex-encoded data for 'txid'.", { {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"}, {"verbose", RPCArg::Type::BOOL, RPCArg::Default{false}, "If false, return a string, otherwise return a json object"}, @@ -241,23 +241,23 @@ static RPCHelpMan getrawtransaction() { RPCResult{"if verbose is not set or set to false", RPCResult::Type::STR, "data", "The serialized, hex-encoded data for 'txid'" - }, - RPCResult{"if verbose is set to true", - RPCResult::Type::OBJ, "", "", - Cat>( - { - {RPCResult::Type::BOOL, "in_active_chain", /*optional=*/true, "Whether specified block is in the active chain or not (only present with explicit \"blockhash\" argument)"}, - {RPCResult::Type::STR_HEX, "blockhash", /*optional=*/true, "the block hash"}, - {RPCResult::Type::NUM, "height", "The block height"}, - {RPCResult::Type::NUM, "confirmations", /*optional=*/true, "The confirmations"}, - {RPCResult::Type::NUM_TIME, "blocktime", /*optional=*/true, "The block time expressed in " + UNIX_EPOCH_TIME}, - {RPCResult::Type::NUM, "time", /*optional=*/true, "Same as \"blocktime\""}, - {RPCResult::Type::BOOL, "instantlock", "Current transaction lock state"}, - {RPCResult::Type::BOOL, "instantlock_internal", "Current internal transaction lock state"}, - {RPCResult::Type::BOOL, "chainlock", "The state of the corresponding block ChainLock"}, - {RPCResult::Type::STR_HEX, "hex", "The serialized, hex-encoded data for 'txid'"}, - }, - DecodeTxDoc(/*txid_field_doc=*/"The transaction id (same as provided)")), + }, + RPCResult{"if verbose is set to true", + RPCResult::Type::OBJ, "", "", + Cat>( + { + {RPCResult::Type::BOOL, "in_active_chain", /*optional=*/true, "Whether specified block is in the active chain or not (only present with explicit \"blockhash\" argument)"}, + {RPCResult::Type::STR_HEX, "blockhash", /*optional=*/true, "the block hash"}, + {RPCResult::Type::NUM, "height", "The block height"}, + {RPCResult::Type::NUM, "confirmations", /*optional=*/true, "The confirmations"}, + {RPCResult::Type::NUM_TIME, "blocktime", /*optional=*/true, "The block time expressed in " + UNIX_EPOCH_TIME}, + {RPCResult::Type::NUM, "time", /*optional=*/true, "Same as \"blocktime\""}, + {RPCResult::Type::BOOL, "instantlock", "Current transaction lock state"}, + {RPCResult::Type::BOOL, "instantlock_internal", "Current internal transaction lock state"}, + {RPCResult::Type::BOOL, "chainlock", "The state of the corresponding block ChainLock"}, + {RPCResult::Type::STR_HEX, "hex", "The serialized, hex-encoded data for 'txid'"}, + }, + DecodeTxDoc(/*txid_field_doc=*/"The transaction id (same as provided)")), }, }, RPCExamples{ @@ -736,21 +736,21 @@ static RPCHelpMan getassetunlockstatuses() static 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" - "Note that the transaction's inputs are not signed, and\n" - "it is not stored in the wallet or transmitted to the network.\n", - CreateTxDoc(), - RPCResult{ - RPCResult::Type::STR_HEX, "transaction", "hex string of the transaction" - }, - RPCExamples{ - HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"address\\\":0.01}]\"") - + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"") - + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"[{\\\"address\\\":0.01}]\"") - + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"[{\\\"data\\\":\\\"00010203\\\"}]\"") - }, + "\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" + "Note that the transaction's inputs are not signed, and\n" + "it is not stored in the wallet or transmitted to the network.\n", + CreateTxDoc(), + RPCResult{ + RPCResult::Type::STR_HEX, "transaction", "hex string of the transaction" + }, + RPCExamples{ + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"address\\\":0.01}]\"") + + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"") + + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"[{\\\"address\\\":0.01}]\"") + + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"[{\\\"data\\\":\\\"00010203\\\"}]\"") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { RPCTypeCheck(request.params, { @@ -851,22 +851,22 @@ static RPCHelpMan decodescript() static 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.", - { - {"txs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The of hex strings of partially signed transactions", + "\nCombine multiple partially signed transactions into one transaction.\n" + "The combined transaction may be another partially signed transaction or a \n" + "fully signed transaction.", { - {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "A hex-encoded raw transaction"}, + {"txs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The of hex strings of partially signed transactions", + { + {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "A hex-encoded raw transaction"}, + }, + }, + }, + RPCResult{ + RPCResult::Type::STR, "", "The hex-encoded raw transaction with signature(s)" }, + RPCExamples{ + HelpExampleCli("combinerawtransaction", R"('["myhex1", "myhex2", "myhex3"]')") }, - }, - RPCResult{ - RPCResult::Type::STR, "", "The hex-encoded raw transaction with signature(s)" - }, - RPCExamples{ - HelpExampleCli("combinerawtransaction", R"('["myhex1", "myhex2", "myhex3"]')") - }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { @@ -937,62 +937,62 @@ static RPCHelpMan combinerawtransaction() static 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" - "The third optional argument (may be null) is an array of previous transaction outputs that\n" - "this transaction depends on but may not yet be in the block chain.\n", - { - {"hexstring", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction hex string"}, - {"privkeys", RPCArg::Type::ARR, RPCArg::Optional::NO, "The base58-encoded private keys for signing", + "\nSign inputs for raw transaction (serialized, hex-encoded).\n" + "The second argument is an array of base58-encoded private\n" + "keys that will be the only keys used to sign the transaction.\n" + "The third optional argument (may be null) is an array of previous transaction outputs that\n" + "this transaction depends on but may not yet be in the block chain.\n", { - {"privatekey", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "private key in base58-encoding"}, - }, - }, - {"prevtxs", RPCArg::Type::ARR, RPCArg::Optional::OMITTED_NAMED_ARG, "The previous dependent transaction outputs", - { - {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "", + {"hexstring", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction hex string"}, + {"privkeys", RPCArg::Type::ARR, RPCArg::Optional::NO, "The base58-encoded private keys for signing", + { + {"privatekey", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "private key in base58-encoding"}, + }, + }, + {"prevtxs", RPCArg::Type::ARR, RPCArg::Optional::OMITTED_NAMED_ARG, "The previous dependent transaction outputs", { - {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"}, - {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"}, - {"scriptPubKey", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "script key"}, - {"redeemScript", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(required for P2SH or P2WSH) redeem script"}, - {"amount", RPCArg::Type::AMOUNT, RPCArg::Optional::OMITTED, "The amount spent"}, + {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "", + { + {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"}, + {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"}, + {"scriptPubKey", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "script key"}, + {"redeemScript", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(required for P2SH or P2WSH) redeem script"}, + {"amount", RPCArg::Type::AMOUNT, RPCArg::Optional::OMITTED, "The amount spent"}, + }, + }, }, }, + {"sighashtype", RPCArg::Type::STR, RPCArg::Default{"ALL"}, "The signature hash type. Must be one of:\n" + " \"ALL\"\n" + " \"NONE\"\n" + " \"SINGLE\"\n" + " \"ALL|ANYONECANPAY\"\n" + " \"NONE|ANYONECANPAY\"\n" + " \"SINGLE|ANYONECANPAY\"\n" + }, }, - }, - {"sighashtype", RPCArg::Type::STR, RPCArg::Default{"ALL"}, "The signature hash type. Must be one of:\n" - " \"ALL\"\n" - " \"NONE\"\n" - " \"SINGLE\"\n" - " \"ALL|ANYONECANPAY\"\n" - " \"NONE|ANYONECANPAY\"\n" - " \"SINGLE|ANYONECANPAY\"\n" - }, - }, - RPCResult{ - RPCResult::Type::OBJ, "", "", - { - {RPCResult::Type::STR_HEX, "hex", "The hex-encoded raw transaction with signature(s)"}, - {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"}, - {RPCResult::Type::ARR, "errors", /*optional=*/true, "Script verification errors (if there are any)", - { - {RPCResult::Type::OBJ, "", "", + RPCResult{ + RPCResult::Type::OBJ, "", "", { - {RPCResult::Type::STR_HEX, "txid", "The hash of the referenced, previous transaction"}, - {RPCResult::Type::NUM, "vout", "The index of the output to spent and used as input"}, - {RPCResult::Type::STR_HEX, "scriptSig", "The hex-encoded signature script"}, - {RPCResult::Type::NUM, "sequence", "Script sequence number"}, - {RPCResult::Type::STR, "error", "Verification or signing error related to the input"}, - }}, - }}, - } - }, - RPCExamples{ - HelpExampleCli("signrawtransactionwithkey", "\"myhex\" \"[\\\"key1\\\",\\\"key2\\\"]\"") - + HelpExampleRpc("signrawtransactionwithkey", "\"myhex\", \"[\\\"key1\\\",\\\"key2\\\"]\"") - }, + {RPCResult::Type::STR_HEX, "hex", "The hex-encoded raw transaction with signature(s)"}, + {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"}, + {RPCResult::Type::ARR, "errors", /*optional=*/true, "Script verification errors (if there are any)", + { + {RPCResult::Type::OBJ, "", "", + { + {RPCResult::Type::STR_HEX, "txid", "The hash of the referenced, previous transaction"}, + {RPCResult::Type::NUM, "vout", "The index of the output to spent and used as input"}, + {RPCResult::Type::STR_HEX, "scriptSig", "The hex-encoded signature script"}, + {RPCResult::Type::NUM, "sequence", "Script sequence number"}, + {RPCResult::Type::STR, "error", "Verification or signing error related to the input"}, + }}, + }}, + } + }, + RPCExamples{ + HelpExampleCli("signrawtransactionwithkey", "\"myhex\" \"[\\\"key1\\\",\\\"key2\\\"]\"") + + HelpExampleRpc("signrawtransactionwithkey", "\"myhex\", \"[\\\"key1\\\",\\\"key2\\\"]\"") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR, UniValue::VARR, UniValue::VSTR}, true); @@ -1142,48 +1142,48 @@ static RPCHelpMan decodepsbt() return RPCHelpMan{ "decodepsbt", "Return a JSON object representing the serialized, base64-encoded partially signed blockchain transaction.", - { - {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "The PSBT base64 string"}, - }, - RPCResult{ - RPCResult::Type::OBJ, "", "", - { - {RPCResult::Type::OBJ, "tx", "The decoded network-serialized unsigned transaction.", - { - {RPCResult::Type::ELISION, "", "The layout is the same as the output of decoderawtransaction."}, - }}, - {RPCResult::Type::ARR, "global_xpubs", "", - { - {RPCResult::Type::OBJ, "", "", - { - {RPCResult::Type::STR, "xpub", "The extended public key this path corresponds to"}, - {RPCResult::Type::STR_HEX, "master_fingerprint", "The fingerprint of the master key"}, - {RPCResult::Type::STR, "path", "The path"}, - }}, - }}, - {RPCResult::Type::NUM, "psbt_version", "The PSBT version number. Not to be confused with the unsigned transaction version"}, - {RPCResult::Type::ARR, "proprietary", "The global proprietary map", { - {RPCResult::Type::OBJ, "", "", + {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "The PSBT base64 string"}, + }, + RPCResult{ + RPCResult::Type::OBJ, "", "", { - {RPCResult::Type::STR_HEX, "identifier", "The hex string for the proprietary identifier"}, - {RPCResult::Type::NUM, "subtype", "The number for the subtype"}, - {RPCResult::Type::STR_HEX, "key", "The hex for the key"}, - {RPCResult::Type::STR_HEX, "value", "The hex for the value"}, - }}, - }}, - {RPCResult::Type::OBJ_DYN, "unknown", "The unknown global fields", - { - {RPCResult::Type::STR_HEX, "key", "(key-value pair) An unknown key-value pair"}, - }}, - decodepsbt_inputs, - decodepsbt_outputs, - {RPCResult::Type::STR_AMOUNT, "fee", /*optional=*/true, "The transaction fee paid if all UTXOs slots in the PSBT have been filled."}, - } - }, - RPCExamples{ - HelpExampleCli("decodepsbt", "\"psbt\"") - }, + {RPCResult::Type::OBJ, "tx", "The decoded network-serialized unsigned transaction.", + { + {RPCResult::Type::ELISION, "", "The layout is the same as the output of decoderawtransaction."}, + }}, + {RPCResult::Type::ARR, "global_xpubs", "", + { + {RPCResult::Type::OBJ, "", "", + { + {RPCResult::Type::STR, "xpub", "The extended public key this path corresponds to"}, + {RPCResult::Type::STR_HEX, "master_fingerprint", "The fingerprint of the master key"}, + {RPCResult::Type::STR, "path", "The path"}, + }}, + }}, + {RPCResult::Type::NUM, "psbt_version", "The PSBT version number. Not to be confused with the unsigned transaction version"}, + {RPCResult::Type::ARR, "proprietary", "The global proprietary map", + { + {RPCResult::Type::OBJ, "", "", + { + {RPCResult::Type::STR_HEX, "identifier", "The hex string for the proprietary identifier"}, + {RPCResult::Type::NUM, "subtype", "The number for the subtype"}, + {RPCResult::Type::STR_HEX, "key", "The hex for the key"}, + {RPCResult::Type::STR_HEX, "value", "The hex for the value"}, + }}, + }}, + {RPCResult::Type::OBJ_DYN, "unknown", "The unknown global fields", + { + {RPCResult::Type::STR_HEX, "key", "(key-value pair) An unknown key-value pair"}, + }}, + decodepsbt_inputs, + decodepsbt_outputs, + {RPCResult::Type::STR_AMOUNT, "fee", /*optional=*/true, "The transaction fee paid if all UTXOs slots in the PSBT have been filled."}, + } + }, + RPCExamples{ + HelpExampleCli("decodepsbt", "\"psbt\"") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { RPCTypeCheck(request.params, {UniValue::VSTR}); @@ -1558,15 +1558,15 @@ static RPCHelpMan finalizepsbt() static RPCHelpMan createpsbt() { return RPCHelpMan{"createpsbt", - "\nCreates a transaction in the Partially Signed Transaction format.\n" - "Implements the Creator role.\n", - CreateTxDoc(), - RPCResult{ - RPCResult::Type::STR, "", "The resulting raw transaction (base64-encoded string)" - }, - RPCExamples{ - HelpExampleCli("createpsbt", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"") - }, + "\nCreates a transaction in the Partially Signed Transaction format.\n" + "Implements the Creator role.\n", + CreateTxDoc(), + RPCResult{ + RPCResult::Type::STR, "", "The resulting raw transaction (base64-encoded string)" + }, + RPCExamples{ + HelpExampleCli("createpsbt", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { @@ -1658,23 +1658,23 @@ static RPCHelpMan converttopsbt() static 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"}, - {"descriptors", RPCArg::Type::ARR, RPCArg::Optional::OMITTED_NAMED_ARG, "An array of either strings or objects", { - {"", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "An output descriptor"}, - {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "An object with an output descriptor and extra information", { - {"desc", RPCArg::Type::STR, RPCArg::Optional::NO, "An output descriptor"}, - {"range", RPCArg::Type::RANGE, RPCArg::Default{1000}, "Up to what index HD chains should be explored (either end or [begin,end])"}, - }}, - }}, - }, - RPCResult { - RPCResult::Type::STR, "", "The base64-encoded partially signed transaction with inputs updated" - }, - RPCExamples { - HelpExampleCli("utxoupdatepsbt", "\"psbt\"") - }, + "\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"}, + {"descriptors", RPCArg::Type::ARR, RPCArg::Optional::OMITTED_NAMED_ARG, "An array of either strings or objects", { + {"", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "An output descriptor"}, + {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "An object with an output descriptor and extra information", { + {"desc", RPCArg::Type::STR, RPCArg::Optional::NO, "An output descriptor"}, + {"range", RPCArg::Type::RANGE, RPCArg::Default{1000}, "Up to what index HD chains should be explored (either end or [begin,end])"}, + }}, + }}, + }, + RPCResult { + RPCResult::Type::STR, "", "The base64-encoded partially signed transaction with inputs updated" + }, + RPCExamples { + HelpExampleCli("utxoupdatepsbt", "\"psbt\"") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR}, true); @@ -1746,20 +1746,20 @@ static RPCHelpMan utxoupdatepsbt() static 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", - { - {"txs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The base64 strings of partially signed transactions", + "\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", { - {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"} - }} - }, - RPCResult { - RPCResult::Type::STR, "", "The base64-encoded partially signed transaction" - }, - RPCExamples { - HelpExampleCli("joinpsbts", "\"psbt\"") - }, + {"txs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The base64 strings of partially signed transactions", + { + {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"} + }} + }, + RPCResult { + RPCResult::Type::STR, "", "The base64-encoded partially signed transaction" + }, + RPCExamples { + HelpExampleCli("joinpsbts", "\"psbt\"") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { RPCTypeCheck(request.params, {UniValue::VARR}, true); @@ -1827,44 +1827,44 @@ static RPCHelpMan joinpsbts() static 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"} - }, - RPCResult { - RPCResult::Type::OBJ, "", "", - { - {RPCResult::Type::ARR, "inputs", /*optional=*/true, "", + "\nAnalyzes and provides information about the current status of a PSBT and its inputs\n", { - {RPCResult::Type::OBJ, "", "", + {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"} + }, + RPCResult { + RPCResult::Type::OBJ, "", "", { - {RPCResult::Type::BOOL, "has_utxo", "Whether a UTXO is provided"}, - {RPCResult::Type::BOOL, "is_final", "Whether the input is finalized"}, - {RPCResult::Type::OBJ, "missing", /*optional=*/true, "Things that are missing that are required to complete this input", + {RPCResult::Type::ARR, "inputs", /*optional=*/true, "", { - {RPCResult::Type::ARR, "pubkeys", /*optional=*/true, "", - { - {RPCResult::Type::STR_HEX, "keyid", "Public key ID, hash160 of the public key, of a public key whose BIP 32 derivation path is missing"}, - }}, - {RPCResult::Type::ARR, "signatures", /*optional=*/true, "", + {RPCResult::Type::OBJ, "", "", { - {RPCResult::Type::STR_HEX, "keyid", "Public key ID, hash160 of the public key, of a public key whose signature is missing"}, + {RPCResult::Type::BOOL, "has_utxo", "Whether a UTXO is provided"}, + {RPCResult::Type::BOOL, "is_final", "Whether the input is finalized"}, + {RPCResult::Type::OBJ, "missing", /*optional=*/true, "Things that are missing that are required to complete this input", + { + {RPCResult::Type::ARR, "pubkeys", /*optional=*/true, "", + { + {RPCResult::Type::STR_HEX, "keyid", "Public key ID, hash160 of the public key, of a public key whose BIP 32 derivation path is missing"}, + }}, + {RPCResult::Type::ARR, "signatures", /*optional=*/true, "", + { + {RPCResult::Type::STR_HEX, "keyid", "Public key ID, hash160 of the public key, of a public key whose signature is missing"}, + }}, + {RPCResult::Type::STR_HEX, "redeemscript", /*optional=*/true, "Hash160 of the redeemScript that is missing"}, + }}, + {RPCResult::Type::STR, "next", /*optional=*/true, "Role of the next person that this input needs to go to"}, }}, - {RPCResult::Type::STR_HEX, "redeemscript", /*optional=*/true, "Hash160 of the redeemScript that is missing"}, }}, - {RPCResult::Type::STR, "next", /*optional=*/true, "Role of the next person that this input needs to go to"}, - }}, - }}, - {RPCResult::Type::NUM, "estimated_vsize", /*optional=*/true, "Estimated vsize of the final signed transaction"}, - {RPCResult::Type::STR_AMOUNT, "estimated_feerate", /*optional=*/true, "Estimated feerate of the final signed transaction in " + CURRENCY_UNIT + "/kB. Shown only if all UTXO slots in the PSBT have been filled"}, - {RPCResult::Type::STR_AMOUNT, "fee", /*optional=*/true, "The transaction fee paid. Shown only if all UTXO slots in the PSBT have been filled"}, - {RPCResult::Type::STR, "next", "Role of the next person that this psbt needs to go to"}, - {RPCResult::Type::STR, "error", /*optional=*/true, "Error message if there is one"}, - } - }, - RPCExamples { - HelpExampleCli("analyzepsbt", "\"psbt\"") - }, + {RPCResult::Type::NUM, "estimated_vsize", /*optional=*/true, "Estimated vsize of the final signed transaction"}, + {RPCResult::Type::STR_AMOUNT, "estimated_feerate", /*optional=*/true, "Estimated feerate of the final signed transaction in " + CURRENCY_UNIT + "/kB. Shown only if all UTXO slots in the PSBT have been filled"}, + {RPCResult::Type::STR_AMOUNT, "fee", /*optional=*/true, "The transaction fee paid. Shown only if all UTXO slots in the PSBT have been filled"}, + {RPCResult::Type::STR, "next", "Role of the next person that this psbt needs to go to"}, + {RPCResult::Type::STR, "error", /*optional=*/true, "Error message if there is one"}, + } + }, + RPCExamples { + HelpExampleCli("analyzepsbt", "\"psbt\"") + }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { RPCTypeCheck(request.params, {UniValue::VSTR}); diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 9cfecfe23bd1..3889e09aa9e2 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -145,17 +145,17 @@ std::string CRPCTable::help(const std::string& strCommand, const JSONRPCRequest& static RPCHelpMan help() { return RPCHelpMan{"help", - "\nList all commands, or get help for a specified command.\n", - { - {"command", RPCArg::Type::STR, RPCArg::DefaultHint{"all commands"}, "The command to get help on"}, - {"subcommand", RPCArg::Type::STR, RPCArg::DefaultHint{"all subcommands"}, "The subcommand to get help on."}, - }, - { - RPCResult{RPCResult::Type::STR, "", "The help text"}, - RPCResult{RPCResult::Type::ANY, "", ""}, - }, - RPCExamples{""}, - [&](const RPCHelpMan& self, const JSONRPCRequest& jsonRequest) -> UniValue + "\nList all commands, or get help for a specified command.\n", + { + {"command", RPCArg::Type::STR, RPCArg::DefaultHint{"all commands"}, "The command to get help on"}, + {"subcommand", RPCArg::Type::STR, RPCArg::DefaultHint{"all subcommands"}, "The subcommand to get help on."}, + }, + { + RPCResult{RPCResult::Type::STR, "", "The help text"}, + RPCResult{RPCResult::Type::ANY, "", ""}, + }, + RPCExamples{""}, + [&](const RPCHelpMan& self, const JSONRPCRequest& jsonRequest) -> UniValue { std::string strCommand, strSubCommand; if (jsonRequest.params.size() > 0) { @@ -174,7 +174,6 @@ static RPCHelpMan help() }; } - static RPCHelpMan stop() { static const std::string RESULT{PACKAGE_NAME " stopping"}; @@ -182,12 +181,12 @@ static RPCHelpMan stop() // Also accept the hidden 'wait' integer argument (milliseconds) // For instance, 'stop 1000' makes the call wait 1 second before returning // to the client (intended for testing) - "\nRequest a graceful shutdown of " PACKAGE_NAME ".", - { - {"wait", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "how long to wait in ms", "", {}, /*hidden=*/true}, - }, - RPCResult{RPCResult::Type::STR, "", "A string with the content '" + RESULT + "'"}, - RPCExamples{""}, + "\nRequest a graceful shutdown of " PACKAGE_NAME ".", + { + {"wait", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "how long to wait in ms", "", {}, /*hidden=*/true}, + }, + RPCResult{RPCResult::Type::STR, "", "A string with the content '" + RESULT + "'"}, + RPCExamples{""}, [&](const RPCHelpMan& self, const JSONRPCRequest& jsonRequest) -> UniValue { // Event loop will exit after current HTTP requests have been handled, so @@ -204,18 +203,17 @@ static RPCHelpMan stop() static RPCHelpMan uptime() { return RPCHelpMan{"uptime", - "\nReturns the total uptime of the server.\n", - {}, - RPCResult{ - RPCResult::Type::NUM, "", "The number of seconds that the server has been running" - }, - RPCExamples{ - HelpExampleCli("uptime", "") - + HelpExampleRpc("uptime", "") - }, - [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue + "\nReturns the total uptime of the server.\n", + {}, + RPCResult{ + RPCResult::Type::NUM, "", "The number of seconds that the server has been running" + }, + RPCExamples{ + HelpExampleCli("uptime", "") + + HelpExampleRpc("uptime", "") + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - return GetTime() - GetStartupTime(); } }; @@ -224,9 +222,9 @@ static RPCHelpMan uptime() static RPCHelpMan getrpcinfo() { return RPCHelpMan{"getrpcinfo", - "\nReturns details of the RPC server.\n", - {}, - RPCResult{ + "\nReturns details of the RPC server.\n", + {}, + RPCResult{ RPCResult::Type::OBJ, "", "", { {RPCResult::Type::ARR, "active_commands", "All active commands", @@ -243,9 +241,8 @@ static RPCHelpMan getrpcinfo() RPCExamples{ HelpExampleCli("getrpcinfo", "") + HelpExampleRpc("getrpcinfo", "")}, - [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - LOCK(g_rpc_server_info.mutex); UniValue active_commands(UniValue::VARR); for (const RPCCommandExecutionInfo& info : g_rpc_server_info.active_commands) { diff --git a/src/rpc/signmessage.cpp b/src/rpc/signmessage.cpp index 9e4867d7e990..58c682a65c9b 100644 --- a/src/rpc/signmessage.cpp +++ b/src/rpc/signmessage.cpp @@ -37,28 +37,28 @@ static RPCHelpMan verifymessage() "\nAs a JSON-RPC call\n" + HelpExampleRpc("verifymessage", "\"" + EXAMPLE_ADDRESS[0] + "\", \"signature\", \"my message\"") }, - [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue -{ - std::string strAddress = request.params[0].get_str(); - std::string strSign = request.params[1].get_str(); - std::string strMessage = request.params[2].get_str(); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue + { + std::string strAddress = request.params[0].get_str(); + std::string strSign = request.params[1].get_str(); + std::string strMessage = request.params[2].get_str(); - switch (MessageVerify(strAddress, strSign, strMessage)) { - case MessageVerificationResult::ERR_INVALID_ADDRESS: - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); - case MessageVerificationResult::ERR_ADDRESS_NO_KEY: - throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key"); - case MessageVerificationResult::ERR_MALFORMED_SIGNATURE: - throw JSONRPCError(RPC_TYPE_ERROR, "Malformed base64 encoding"); - case MessageVerificationResult::ERR_PUBKEY_NOT_RECOVERED: - case MessageVerificationResult::ERR_NOT_SIGNED: - return false; - case MessageVerificationResult::OK: - return true; - } + switch (MessageVerify(strAddress, strSign, strMessage)) { + case MessageVerificationResult::ERR_INVALID_ADDRESS: + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); + case MessageVerificationResult::ERR_ADDRESS_NO_KEY: + throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key"); + case MessageVerificationResult::ERR_MALFORMED_SIGNATURE: + throw JSONRPCError(RPC_TYPE_ERROR, "Malformed base64 encoding"); + case MessageVerificationResult::ERR_PUBKEY_NOT_RECOVERED: + case MessageVerificationResult::ERR_NOT_SIGNED: + return false; + case MessageVerificationResult::OK: + return true; + } - return false; -}, + return false; + }, }; } @@ -81,25 +81,24 @@ static RPCHelpMan signmessagewithprivkey() "\nAs a JSON-RPC call\n" + HelpExampleRpc("signmessagewithprivkey", "\"privkey\", \"my message\"") }, - [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue -{ + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue + { + std::string strPrivkey = request.params[0].get_str(); + std::string strMessage = request.params[1].get_str(); - std::string strPrivkey = request.params[0].get_str(); - std::string strMessage = request.params[1].get_str(); + CKey key = DecodeSecret(strPrivkey); + if (!key.IsValid()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key"); + } - CKey key = DecodeSecret(strPrivkey); - if (!key.IsValid()) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key"); - } + std::string signature; - std::string signature; + if (!MessageSign(key, strMessage, signature)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed"); + } - if (!MessageSign(key, strMessage, signature)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed"); - } - - return signature; -}, + return signature; + }, }; } diff --git a/src/rpc/txoutproof.cpp b/src/rpc/txoutproof.cpp index 168a47cb1a87..bf7b8dc2e069 100644 --- a/src/rpc/txoutproof.cpp +++ b/src/rpc/txoutproof.cpp @@ -45,81 +45,81 @@ static RPCHelpMan gettxoutproof() + HelpExampleRpc("gettxoutproof", "[\"mytxid\",...], \"blockhash\"") }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue -{ - std::set setTxids; - UniValue txids = request.params[0].get_array(); - if (txids.empty()) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Parameter 'txids' cannot be empty"); - } - for (unsigned int idx = 0; idx < txids.size(); idx++) { - auto ret = setTxids.insert(ParseHashV(txids[idx], "txid")); - if (!ret.second) { - throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated txid: ") + txids[idx].get_str()); - } - } + { + std::set setTxids; + UniValue txids = request.params[0].get_array(); + if (txids.empty()) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Parameter 'txids' cannot be empty"); + } + for (unsigned int idx = 0; idx < txids.size(); idx++) { + auto ret = setTxids.insert(ParseHashV(txids[idx], "txid")); + if (!ret.second) { + throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated txid: ") + txids[idx].get_str()); + } + } - const CBlockIndex* pblockindex = nullptr; - uint256 hashBlock; - ChainstateManager& chainman = EnsureAnyChainman(request.context); - if (!request.params[1].isNull()) { - LOCK(cs_main); - hashBlock = ParseHashV(request.params[1], "blockhash"); - pblockindex = chainman.m_blockman.LookupBlockIndex(hashBlock); - if (!pblockindex) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); - } - } else { - LOCK(cs_main); - CChainState& active_chainstate = chainman.ActiveChainstate(); - - // Loop through txids and try to find which block they're in. Exit loop once a block is found. - for (const auto& tx : setTxids) { - const Coin& coin = AccessByTxid(active_chainstate.CoinsTip(), tx); - if (!coin.IsSpent()) { - pblockindex = active_chainstate.m_chain[coin.nHeight]; - break; + const CBlockIndex* pblockindex = nullptr; + uint256 hashBlock; + ChainstateManager& chainman = EnsureAnyChainman(request.context); + if (!request.params[1].isNull()) { + LOCK(cs_main); + hashBlock = ParseHashV(request.params[1], "blockhash"); + pblockindex = chainman.m_blockman.LookupBlockIndex(hashBlock); + if (!pblockindex) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); + } + } else { + LOCK(cs_main); + CChainState& active_chainstate = chainman.ActiveChainstate(); + + // Loop through txids and try to find which block they're in. Exit loop once a block is found. + for (const auto& tx : setTxids) { + const Coin& coin = AccessByTxid(active_chainstate.CoinsTip(), tx); + if (!coin.IsSpent()) { + pblockindex = active_chainstate.m_chain[coin.nHeight]; + break; + } + } } - } - } - // Allow txindex to catch up if we need to query it and before we acquire cs_main. - if (g_txindex && !pblockindex) { - g_txindex->BlockUntilSyncedToCurrentChain(); - } + // Allow txindex to catch up if we need to query it and before we acquire cs_main. + if (g_txindex && !pblockindex) { + g_txindex->BlockUntilSyncedToCurrentChain(); + } - if (pblockindex == nullptr) { - const CTransactionRef tx = GetTransaction(/*block_index=*/nullptr, /*mempool=*/nullptr, *setTxids.begin(), Params().GetConsensus(), hashBlock); - if (!tx || hashBlock.IsNull()) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block"); - } - pblockindex = WITH_LOCK(::cs_main, return chainman.m_blockman.LookupBlockIndex(hashBlock)); - if (!pblockindex) { - throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction index corrupt"); - } - } + if (pblockindex == nullptr) { + const CTransactionRef tx = GetTransaction(/*block_index=*/nullptr, /*mempool=*/nullptr, *setTxids.begin(), Params().GetConsensus(), hashBlock); + if (!tx || hashBlock.IsNull()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block"); + } + pblockindex = WITH_LOCK(::cs_main, return chainman.m_blockman.LookupBlockIndex(hashBlock)); + if (!pblockindex) { + throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction index corrupt"); + } + } - CBlock block; - if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) { - throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); - } + CBlock block; + if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) { + throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); + } - unsigned int ntxFound = 0; - for (const auto& tx : block.vtx) { - if (setTxids.count(tx->GetHash())) { - ntxFound++; - } - } - if (ntxFound != setTxids.size()) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Not all transactions found in specified or retrieved block"); - } + unsigned int ntxFound = 0; + for (const auto& tx : block.vtx) { + if (setTxids.count(tx->GetHash())) { + ntxFound++; + } + } + if (ntxFound != setTxids.size()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Not all transactions found in specified or retrieved block"); + } - CDataStream ssMB(SER_NETWORK, PROTOCOL_VERSION); - CMerkleBlock mb(block, setTxids); - ssMB << mb; - std::string strHex = HexStr(ssMB); - return strHex; -}, + CDataStream ssMB(SER_NETWORK, PROTOCOL_VERSION); + CMerkleBlock mb(block, setTxids); + ssMB << mb; + std::string strHex = HexStr(ssMB); + return strHex; + }, }; } @@ -142,35 +142,35 @@ static RPCHelpMan verifytxoutproof() + HelpExampleRpc("gettxoutproof", "\"proof\"") }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue -{ - CDataStream ssMB(ParseHexV(request.params[0], "proof"), SER_NETWORK, PROTOCOL_VERSION); - CMerkleBlock merkleBlock; - ssMB >> merkleBlock; + { + CDataStream ssMB(ParseHexV(request.params[0], "proof"), SER_NETWORK, PROTOCOL_VERSION); + CMerkleBlock merkleBlock; + ssMB >> merkleBlock; - UniValue res(UniValue::VARR); + UniValue res(UniValue::VARR); - std::vector vMatch; - std::vector vIndex; - if (merkleBlock.txn.ExtractMatches(vMatch, vIndex) != merkleBlock.header.hashMerkleRoot) - return res; + std::vector vMatch; + std::vector vIndex; + if (merkleBlock.txn.ExtractMatches(vMatch, vIndex) != merkleBlock.header.hashMerkleRoot) + return res; - ChainstateManager& chainman = EnsureAnyChainman(request.context); - LOCK(cs_main); + ChainstateManager& chainman = EnsureAnyChainman(request.context); + LOCK(cs_main); - const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(merkleBlock.header.GetHash()); - if (!pindex || !chainman.ActiveChain().Contains(pindex) || pindex->nTx == 0) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found in chain"); - } + const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(merkleBlock.header.GetHash()); + if (!pindex || !chainman.ActiveChain().Contains(pindex) || pindex->nTx == 0) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found in chain"); + } - // Check if proof is valid, only add results if so - if (pindex->nTx == merkleBlock.txn.GetNumTransactions()) { - for (const uint256& hash : vMatch) { - res.push_back(hash.GetHex()); - } - } + // Check if proof is valid, only add results if so + if (pindex->nTx == merkleBlock.txn.GetNumTransactions()) { + for (const uint256& hash : vMatch) { + res.push_back(hash.GetHex()); + } + } - return res; -}, + return res; + }, }; } From 1a49e0fec9f6be6c7f298ffce1b5e99d134bfeb6 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Wed, 4 Feb 2026 23:59:30 +0700 Subject: [PATCH 2/2] refactor: change function order to unify with Bitcoin Core in rpc/node --- src/rpc/node.cpp | 85 ++++++++++++++++++++++++------------------------ 1 file changed, 43 insertions(+), 42 deletions(-) diff --git a/src/rpc/node.cpp b/src/rpc/node.cpp index 69616dd8f855..a095d2f42a54 100644 --- a/src/rpc/node.cpp +++ b/src/rpc/node.cpp @@ -1048,11 +1048,53 @@ static RPCHelpMan echo(const std::string& name) if (request.params[9].isStr()) { CHECK_NONFATAL(request.params[9].get_str() != "trigger_internal_bug"); } + return request.params; }, }; } +static RPCHelpMan echo() { return echo("echo"); } +static RPCHelpMan echojson() { return echo("echojson"); } + +static RPCHelpMan echoipc() +{ + return RPCHelpMan{ + "echoipc", + "\nEcho back the input argument, passing it through a spawned process in a multiprocess build.\n" + "This command is for testing.\n", + {{"arg", RPCArg::Type::STR, RPCArg::Optional::NO, "The string to echo",}}, + RPCResult{RPCResult::Type::STR, "echo", "The echoed string."}, + RPCExamples{HelpExampleCli("echo", "\"Hello world\"") + + HelpExampleRpc("echo", "\"Hello world\"")}, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { + interfaces::Init& local_init = *EnsureAnyNodeContext(request.context).init; + std::unique_ptr echo; + if (interfaces::Ipc* ipc = local_init.ipc()) { + // Spawn a new bitcoin-node process and call makeEcho to get a + // client pointer to a interfaces::Echo instance running in + // that process. This is just for testing. A slightly more + // realistic test spawning a different executable instead of + // the same executable would add a new bitcoin-echo executable, + // and spawn bitcoin-echo below instead of bitcoin-node. But + // using bitcoin-node avoids the need to build and install a + // new executable just for this one test. + auto init = ipc->spawnProcess("dash-node"); + echo = init->makeEcho(); + ipc->addCleanup(*echo, [init = init.release()] { delete init; }); + } else { + // IPC support is not available because this is a bitcoind + // process not a bitcoind-node process, so just create a local + // interfaces::Echo object and return it so the `echoipc` RPC + // method will work, and the python test calling `echoipc` + // can expect the same result. + echo = local_init.makeEcho(); + } + return echo->echo(request.params[0].get_str()); + }, + }; +} + static UniValue SummaryToJSON(const IndexSummary&& summary, std::string index_name) { UniValue ret_summary(UniValue::VOBJ); @@ -1107,48 +1149,7 @@ static RPCHelpMan getindexinfo() }); return result; -} - }; -} - -static RPCHelpMan echo() { return echo("echo"); } -static RPCHelpMan echojson() { return echo("echojson"); } - -static RPCHelpMan echoipc() -{ - return RPCHelpMan{ - "echoipc", - "\nEcho back the input argument, passing it through a spawned process in a multiprocess build.\n" - "This command is for testing.\n", - {{"arg", RPCArg::Type::STR, RPCArg::Optional::NO, "The string to echo",}}, - RPCResult{RPCResult::Type::STR, "echo", "The echoed string."}, - RPCExamples{HelpExampleCli("echo", "\"Hello world\"") + - HelpExampleRpc("echo", "\"Hello world\"")}, - [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - interfaces::Init& local_init = *EnsureAnyNodeContext(request.context).init; - std::unique_ptr echo; - if (interfaces::Ipc* ipc = local_init.ipc()) { - // Spawn a new bitcoin-node process and call makeEcho to get a - // client pointer to a interfaces::Echo instance running in - // that process. This is just for testing. A slightly more - // realistic test spawning a different executable instead of - // the same executable would add a new bitcoin-echo executable, - // and spawn bitcoin-echo below instead of bitcoin-node. But - // using bitcoin-node avoids the need to build and install a - // new executable just for this one test. - auto init = ipc->spawnProcess("dash-node"); - echo = init->makeEcho(); - ipc->addCleanup(*echo, [init = init.release()] { delete init; }); - } else { - // IPC support is not available because this is a bitcoind - // process not a bitcoind-node process, so just create a local - // interfaces::Echo object and return it so the `echoipc` RPC - // method will work, and the python test calling `echoipc` - // can expect the same result. - echo = local_init.makeEcho(); - } - return echo->echo(request.params[0].get_str()); - }, +}, }; }