aboutsummaryrefslogtreecommitdiff
path: root/src/rpc/mining.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/rpc/mining.cpp')
-rw-r--r--src/rpc/mining.cpp232
1 files changed, 119 insertions, 113 deletions
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index 623b0bd86a..2fd6f99be5 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -18,12 +18,14 @@
#include <rpc/blockchain.h>
#include <rpc/mining.h>
#include <rpc/server.h>
+#include <rpc/util.h>
#include <shutdown.h>
#include <txmempool.h>
-#include <util.h>
-#include <utilstrencodings.h>
+#include <util/strencodings.h>
+#include <util/system.h>
#include <validation.h>
#include <validationinterface.h>
+#include <versionbitsinfo.h>
#include <warnings.h>
#include <memory>
@@ -85,13 +87,15 @@ static UniValue getnetworkhashps(const JSONRPCRequest& request)
{
if (request.fHelp || request.params.size() > 2)
throw std::runtime_error(
- "getnetworkhashps ( nblocks height )\n"
- "\nReturns the estimated network hashes per second based on the last n blocks.\n"
- "Pass in [blocks] to override # of blocks, -1 specifies since last difficulty change.\n"
- "Pass in [height] to estimate the network speed at the time when a certain block was found.\n"
- "\nArguments:\n"
- "1. nblocks (numeric, optional, default=120) The number of blocks, or -1 for blocks since last difficulty change.\n"
- "2. height (numeric, optional, default=-1) To estimate at the time of the given height.\n"
+ RPCHelpMan{"getnetworkhashps",
+ "\nReturns the estimated network hashes per second based on the last n blocks.\n"
+ "Pass in [blocks] to override # of blocks, -1 specifies since last difficulty change.\n"
+ "Pass in [height] to estimate the network speed at the time when a certain block was found.\n",
+ {
+ {"nblocks", RPCArg::Type::NUM, /* opt */ true, /* default_val */ "120", "The number of blocks, or -1 for blocks since last difficulty change."},
+ {"height", RPCArg::Type::NUM, /* opt */ true, /* default_val */ "-1", "To estimate at the time of the given height."},
+ }}
+ .ToString() +
"\nResult:\n"
"x (numeric) Hashes per second estimated\n"
"\nExamples:\n"
@@ -155,17 +159,21 @@ static UniValue generatetoaddress(const JSONRPCRequest& request)
{
if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
throw std::runtime_error(
- "generatetoaddress nblocks address (maxtries)\n"
- "\nMine blocks immediately to a specified address (before the RPC call returns)\n"
- "\nArguments:\n"
- "1. nblocks (numeric, required) How many blocks are generated immediately.\n"
- "2. address (string, required) The address to send the newly generated bitcoin to.\n"
- "3. maxtries (numeric, optional) How many iterations to try (default = 1000000).\n"
+ RPCHelpMan{"generatetoaddress",
+ "\nMine blocks immediately to a specified address (before the RPC call returns)\n",
+ {
+ {"nblocks", RPCArg::Type::NUM, /* opt */ false, /* default_val */ "", "How many blocks are generated immediately."},
+ {"address", RPCArg::Type::STR, /* opt */ false, /* default_val */ "", "The address to send the newly generated bitcoin to."},
+ {"maxtries", RPCArg::Type::NUM, /* opt */ true, /* default_val */ "1000000", "How many iterations to try."},
+ }}
+ .ToString() +
"\nResult:\n"
"[ blockhashes ] (array) hashes of blocks generated\n"
"\nExamples:\n"
"\nGenerate 11 blocks to myaddress\n"
+ HelpExampleCli("generatetoaddress", "11 \"myaddress\"")
+ + "If you are running the bitcoin core wallet, you can get a new address to send the newly generated bitcoin to with:\n"
+ + HelpExampleCli("getnewaddress", "")
);
int nGenerate = request.params[0].get_int();
@@ -189,8 +197,9 @@ static UniValue getmininginfo(const JSONRPCRequest& request)
{
if (request.fHelp || request.params.size() != 0)
throw std::runtime_error(
- "getmininginfo\n"
- "\nReturns a json object containing mining-related information."
+ RPCHelpMan{"getmininginfo",
+ "\nReturns a json object containing mining-related information.", {}}
+ .ToString() +
"\nResult:\n"
"{\n"
" \"blocks\": nnn, (numeric) The current block\n"
@@ -228,16 +237,18 @@ static UniValue prioritisetransaction(const JSONRPCRequest& request)
{
if (request.fHelp || request.params.size() != 3)
throw std::runtime_error(
- "prioritisetransaction <txid> <dummy value> <fee delta>\n"
- "Accepts the transaction into mined blocks at a higher (or lower) priority\n"
- "\nArguments:\n"
- "1. \"txid\" (string, required) The transaction id.\n"
- "2. dummy (numeric, optional) API-Compatibility for previous API. Must be zero or null.\n"
- " DEPRECATED. For forward compatibility use named arguments and omit this parameter.\n"
- "3. fee_delta (numeric, required) The fee value (in satoshis) to add (or subtract, if negative).\n"
+ RPCHelpMan{"prioritisetransaction",
+ "Accepts the transaction into mined blocks at a higher (or lower) priority\n",
+ {
+ {"txid", RPCArg::Type::STR_HEX, /* opt */ false, /* default_val */ "", "The transaction id."},
+ {"dummy", RPCArg::Type::NUM, /* opt */ true, /* default_val */ "null", "API-Compatibility for previous API. Must be zero or null.\n"
+ " DEPRECATED. For forward compatibility use named arguments and omit this parameter."},
+ {"fee_delta", RPCArg::Type::NUM, /* opt */ false, /* default_val */ "", "The fee value (in satoshis) to add (or subtract, if negative).\n"
" Note, that this value is not a fee rate. It is a value to modify absolute fee of the TX.\n"
" The fee is not actually paid, only the algorithm for selecting transactions into a block\n"
- " considers the transaction as it would have paid a higher (or lower) fee.\n"
+ " considers the transaction as it would have paid a higher (or lower) fee."},
+ }}
+ .ToString() +
"\nResult:\n"
"true (boolean) Returns true\n"
"\nExamples:\n"
@@ -247,7 +258,7 @@ static UniValue prioritisetransaction(const JSONRPCRequest& request)
LOCK(cs_main);
- uint256 hash = ParseHashStr(request.params[0].get_str(), "txid");
+ uint256 hash(ParseHashV(request.params[0], "txid"));
CAmount nAmount = request.params[2].get_int64();
if (!(request.params[1].isNull() || request.params[1].get_real() == 0)) {
@@ -291,30 +302,32 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
{
if (request.fHelp || request.params.size() > 1)
throw std::runtime_error(
- "getblocktemplate ( TemplateRequest )\n"
- "\nIf the request parameters include a 'mode' key, that is used to explicitly select between the default 'template' request or a 'proposal'.\n"
- "It returns data needed to construct a block to work on.\n"
- "For full specification, see BIPs 22, 23, 9, and 145:\n"
- " https://github.com/bitcoin/bips/blob/master/bip-0022.mediawiki\n"
- " https://github.com/bitcoin/bips/blob/master/bip-0023.mediawiki\n"
- " https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki#getblocktemplate_changes\n"
- " https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki\n"
-
- "\nArguments:\n"
- "1. template_request (json object, optional) A json object in the following spec\n"
- " {\n"
- " \"mode\":\"template\" (string, optional) This must be set to \"template\", \"proposal\" (see BIP 23), or omitted\n"
- " \"capabilities\":[ (array, optional) A list of strings\n"
- " \"support\" (string) client side supported feature, 'longpoll', 'coinbasetxn', 'coinbasevalue', 'proposal', 'serverlist', 'workid'\n"
- " ,...\n"
- " ],\n"
- " \"rules\":[ (array, optional) A list of strings\n"
- " \"support\" (string) client side supported softfork deployment\n"
- " ,...\n"
- " ]\n"
- " }\n"
- "\n"
-
+ RPCHelpMan{"getblocktemplate",
+ "\nIf the request parameters include a 'mode' key, that is used to explicitly select between the default 'template' request or a 'proposal'.\n"
+ "It returns data needed to construct a block to work on.\n"
+ "For full specification, see BIPs 22, 23, 9, and 145:\n"
+ " https://github.com/bitcoin/bips/blob/master/bip-0022.mediawiki\n"
+ " https://github.com/bitcoin/bips/blob/master/bip-0023.mediawiki\n"
+ " https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki#getblocktemplate_changes\n"
+ " https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki\n",
+ {
+ {"template_request", RPCArg::Type::OBJ, /* opt */ false, /* default_val */ "", "A json object in the following spec",
+ {
+ {"mode", RPCArg::Type::STR, /* opt */ true, /* default_val */ "", "This must be set to \"template\", \"proposal\" (see BIP 23), or omitted"},
+ {"capabilities", RPCArg::Type::ARR, /* opt */ true, /* default_val */ "", "A list of strings",
+ {
+ {"support", RPCArg::Type::STR, /* opt */ true, /* default_val */ "", "client side supported feature, 'longpoll', 'coinbasetxn', 'coinbasevalue', 'proposal', 'serverlist', 'workid'"},
+ },
+ },
+ {"rules", RPCArg::Type::ARR, /* opt */ false, /* default_val */ "", "A list of strings",
+ {
+ {"support", RPCArg::Type::STR, /* opt */ true, /* default_val */ "", "client side supported softfork deployment"},
+ },
+ },
+ },
+ "\"template_request\""},
+ }}
+ .ToString() +
"\nResult:\n"
"{\n"
" \"version\" : n, (numeric) The preferred block version\n"
@@ -361,8 +374,8 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
"}\n"
"\nExamples:\n"
- + HelpExampleCli("getblocktemplate", "")
- + HelpExampleRpc("getblocktemplate", "")
+ + HelpExampleCli("getblocktemplate", "{\"rules\": [\"segwit\"]}")
+ + HelpExampleRpc("getblocktemplate", "{\"rules\": [\"segwit\"]}")
);
LOCK(cs_main);
@@ -455,7 +468,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
// Format: <hashBestChain><nTransactionsUpdatedLast>
std::string lpstr = lpval.get_str();
- hashWatchedChain.SetHex(lpstr.substr(0, 64));
+ hashWatchedChain = ParseHashV(lpstr.substr(0, 64), "longpollid");
nTransactionsUpdatedLastLP = atoi64(lpstr.substr(64));
}
else
@@ -470,7 +483,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
{
checktxtime = std::chrono::steady_clock::now() + std::chrono::minutes(1);
- WaitableLock lock(g_best_block_mutex);
+ WAIT_LOCK(g_best_block_mutex, lock);
while (g_best_block == hashWatchedChain && IsRPCRunning())
{
if (g_best_block_cv.wait_until(lock, checktxtime) == std::cv_status::timeout)
@@ -490,21 +503,17 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
}
const struct VBDeploymentInfo& segwit_info = VersionBitsDeploymentInfo[Consensus::DEPLOYMENT_SEGWIT];
- // If the caller is indicating segwit support, then allow CreateNewBlock()
- // to select witness transactions, after segwit activates (otherwise
- // don't).
- bool fSupportsSegwit = setClientRules.find(segwit_info.name) != setClientRules.end();
+ // GBT must be called with 'segwit' set in the rules
+ if (setClientRules.count(segwit_info.name) != 1) {
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "getblocktemplate must be called with the segwit rule set (call with {\"rules\": [\"segwit\"]})");
+ }
// Update block
static CBlockIndex* pindexPrev;
static int64_t nStart;
static std::unique_ptr<CBlockTemplate> pblocktemplate;
- // Cache whether the last invocation was with segwit support, to avoid returning
- // a segwit-block to a non-segwit caller.
- static bool fLastTemplateSupportsSegwit = true;
if (pindexPrev != chainActive.Tip() ||
- (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 5) ||
- fLastTemplateSupportsSegwit != fSupportsSegwit)
+ (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 5))
{
// Clear pindexPrev so future calls make a new block, despite any failures from here on
pindexPrev = nullptr;
@@ -513,11 +522,10 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
CBlockIndex* pindexPrevNew = chainActive.Tip();
nStart = GetTime();
- fLastTemplateSupportsSegwit = fSupportsSegwit;
// Create new block
CScript scriptDummy = CScript() << OP_TRUE;
- pblocktemplate = BlockAssembler(Params()).CreateNewBlock(scriptDummy, fSupportsSegwit);
+ pblocktemplate = BlockAssembler(Params()).CreateNewBlock(scriptDummy);
if (!pblocktemplate)
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
@@ -669,7 +677,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
result.pushKV("bits", strprintf("%08x", pblock->nBits));
result.pushKV("height", (int64_t)(pindexPrev->nHeight+1));
- if (!pblocktemplate->vchCoinbaseCommitment.empty() && fSupportsSegwit) {
+ if (!pblocktemplate->vchCoinbaseCommitment.empty()) {
result.pushKV("default_witness_commitment", HexStr(pblocktemplate->vchCoinbaseCommitment.begin(), pblocktemplate->vchCoinbaseCommitment.end()));
}
@@ -699,13 +707,14 @@ static UniValue submitblock(const JSONRPCRequest& request)
// We allow 2 arguments for compliance with BIP22. Argument 2 is ignored.
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) {
throw std::runtime_error(
- "submitblock \"hexdata\" ( \"dummy\" )\n"
- "\nAttempts to submit new block to network.\n"
- "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n"
-
- "\nArguments\n"
- "1. \"hexdata\" (string, required) the hex-encoded block data to submit\n"
- "2. \"dummy\" (optional) dummy value, for compatibility with BIP22. This value is ignored.\n"
+ RPCHelpMan{"submitblock",
+ "\nAttempts to submit new block to network.\n"
+ "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n",
+ {
+ {"hexdata", RPCArg::Type::STR_HEX, /* opt */ false, /* default_val */ "", "the hex-encoded block data to submit"},
+ {"dummy", RPCArg::Type::STR, /* opt */ true, /* default_val */ "ignored", "dummy value, for compatibility with BIP22. This value is ignored."},
+ }}
+ .ToString() +
"\nResult:\n"
"\nExamples:\n"
+ HelpExampleCli("submitblock", "\"mydata\"")
@@ -750,11 +759,7 @@ static UniValue submitblock(const JSONRPCRequest& request)
RegisterValidationInterface(&sc);
bool accepted = ProcessNewBlock(Params(), blockptr, /* fForceProcessing */ true, /* fNewBlock */ &new_block);
UnregisterValidationInterface(&sc);
- if (!new_block) {
- if (!accepted) {
- // TODO Maybe pass down fNewBlock to AcceptBlockHeader, so it is properly set to true in this case?
- return "invalid";
- }
+ if (!new_block && accepted) {
return "duplicate";
}
if (!sc.found) {
@@ -767,11 +772,13 @@ static UniValue submitheader(const JSONRPCRequest& request)
{
if (request.fHelp || request.params.size() != 1) {
throw std::runtime_error(
- "submitheader \"hexdata\"\n"
- "\nDecode the given hexdata as a header and submit it as a candidate chain tip if valid."
- "\nThrows when the header is invalid.\n"
- "\nArguments\n"
- "1. \"hexdata\" (string, required) the hex-encoded block header data\n"
+ 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, /* opt */ false, /* default_val */ "", "the hex-encoded block header data"},
+ }}
+ .ToString() +
"\nResult:\n"
"None"
"\nExamples:\n" +
@@ -799,32 +806,28 @@ static UniValue submitheader(const JSONRPCRequest& request)
throw JSONRPCError(RPC_VERIFY_ERROR, state.GetRejectReason());
}
-static UniValue estimatefee(const JSONRPCRequest& request)
-{
- throw JSONRPCError(RPC_METHOD_DEPRECATED, "estimatefee was removed in v0.17.\n"
- "Clients should use estimatesmartfee.");
-}
-
static UniValue estimatesmartfee(const JSONRPCRequest& request)
{
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
throw std::runtime_error(
- "estimatesmartfee conf_target (\"estimate_mode\")\n"
- "\nEstimates the approximate fee per kilobyte needed for a transaction to begin\n"
- "confirmation within conf_target blocks if possible and return the number of blocks\n"
- "for which the estimate is valid. Uses virtual transaction size as defined\n"
- "in BIP 141 (witness data is discounted).\n"
- "\nArguments:\n"
- "1. conf_target (numeric) Confirmation target in blocks (1 - 1008)\n"
- "2. \"estimate_mode\" (string, optional, default=CONSERVATIVE) The fee estimate mode.\n"
+ RPCHelpMan{"estimatesmartfee",
+ "\nEstimates the approximate fee per kilobyte needed for a transaction to begin\n"
+ "confirmation within conf_target blocks if possible and return the number of blocks\n"
+ "for which the estimate is valid. Uses virtual transaction size as defined\n"
+ "in BIP 141 (witness data is discounted).\n",
+ {
+ {"conf_target", RPCArg::Type::NUM, /* opt */ false, /* default_val */ "", "Confirmation target in blocks (1 - 1008)"},
+ {"estimate_mode", RPCArg::Type::STR, /* opt */ true, /* default_val */ "CONSERVATIVE", "The fee estimate mode.\n"
" Whether to return a more conservative estimate which also satisfies\n"
" a longer history. A conservative estimate potentially returns a\n"
" higher feerate and is more likely to be sufficient for the desired\n"
" target, but is not as responsive to short term drops in the\n"
" prevailing fee market. Must be one of:\n"
- " \"UNSET\" (defaults to CONSERVATIVE)\n"
+ " \"UNSET\"\n"
" \"ECONOMICAL\"\n"
- " \"CONSERVATIVE\"\n"
+ " \"CONSERVATIVE\""},
+ }}
+ .ToString() +
"\nResult:\n"
"{\n"
" \"feerate\" : x.x, (numeric, optional) estimate fee rate in " + CURRENCY_UNIT + "/kB\n"
@@ -870,19 +873,21 @@ static UniValue estimaterawfee(const JSONRPCRequest& request)
{
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
throw std::runtime_error(
- "estimaterawfee conf_target (threshold)\n"
- "\nWARNING: This interface is unstable and may disappear or change!\n"
- "\nWARNING: This is an advanced API call that is tightly coupled to the specific\n"
- " implementation of fee estimation. The parameters it can be called with\n"
- " and the results it returns will change if the internal implementation changes.\n"
- "\nEstimates the approximate fee per kilobyte needed for a transaction to begin\n"
- "confirmation within conf_target blocks if possible. Uses virtual transaction size as\n"
- "defined in BIP 141 (witness data is discounted).\n"
- "\nArguments:\n"
- "1. conf_target (numeric) Confirmation target in blocks (1 - 1008)\n"
- "2. threshold (numeric, optional) The proportion of transactions in a given feerate range that must have been\n"
+ RPCHelpMan{"estimaterawfee",
+ "\nWARNING: This interface is unstable and may disappear or change!\n"
+ "\nWARNING: This is an advanced API call that is tightly coupled to the specific\n"
+ " implementation of fee estimation. The parameters it can be called with\n"
+ " and the results it returns will change if the internal implementation changes.\n"
+ "\nEstimates the approximate fee per kilobyte needed for a transaction to begin\n"
+ "confirmation within conf_target blocks if possible. Uses virtual transaction size as\n"
+ "defined in BIP 141 (witness data is discounted).\n",
+ {
+ {"conf_target", RPCArg::Type::NUM, /* opt */ false, /* default_val */ "", "Confirmation target in blocks (1 - 1008)"},
+ {"threshold", RPCArg::Type::NUM, /* opt */ true, /* default_val */ "0.95", "The proportion of transactions in a given feerate range that must have been\n"
" confirmed within conf_target in order to consider those feerates as high enough and proceed to check\n"
- " lower buckets. Default: 0.95\n"
+ " lower buckets."},
+ }}
+ .ToString() +
"\nResult:\n"
"{\n"
" \"short\" : { (json object, optional) estimate for short time horizon\n"
@@ -922,7 +927,7 @@ static UniValue estimaterawfee(const JSONRPCRequest& request)
UniValue result(UniValue::VOBJ);
- for (FeeEstimateHorizon horizon : {FeeEstimateHorizon::SHORT_HALFLIFE, FeeEstimateHorizon::MED_HALFLIFE, FeeEstimateHorizon::LONG_HALFLIFE}) {
+ for (const FeeEstimateHorizon horizon : {FeeEstimateHorizon::SHORT_HALFLIFE, FeeEstimateHorizon::MED_HALFLIFE, FeeEstimateHorizon::LONG_HALFLIFE}) {
CFeeRate feeRate;
EstimationResult buckets;
@@ -968,6 +973,7 @@ static UniValue estimaterawfee(const JSONRPCRequest& request)
return result;
}
+// clang-format off
static const CRPCCommand commands[] =
{ // category name actor (function) argNames
// --------------------- ------------------------ ----------------------- ----------
@@ -981,11 +987,11 @@ static const CRPCCommand commands[] =
{ "generating", "generatetoaddress", &generatetoaddress, {"nblocks","address","maxtries"} },
- { "hidden", "estimatefee", &estimatefee, {} },
{ "util", "estimatesmartfee", &estimatesmartfee, {"conf_target", "estimate_mode"} },
{ "hidden", "estimaterawfee", &estimaterawfee, {"conf_target", "threshold"} },
};
+// clang-format on
void RegisterMiningRPCCommands(CRPCTable &t)
{