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.cpp157
1 files changed, 95 insertions, 62 deletions
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index fee6a893eb..a561b7e93c 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -81,9 +81,9 @@ static UniValue GetNetworkHashPS(int lookup, int height) {
return workDiff.getdouble() / timeDiff;
}
-static UniValue getnetworkhashps(const JSONRPCRequest& request)
+static RPCHelpMan getnetworkhashps()
{
- RPCHelpMan{"getnetworkhashps",
+ return RPCHelpMan{"getnetworkhashps",
"\nReturns the estimated network hashes per second based on the last n blocks.\n"
"Pass in [blocks] to override # of blocks, -1 specifies since last difficulty change.\n"
"Pass in [height] to estimate the network speed at the time when a certain block was found.\n",
@@ -97,10 +97,12 @@ static UniValue getnetworkhashps(const JSONRPCRequest& request)
HelpExampleCli("getnetworkhashps", "")
+ HelpExampleRpc("getnetworkhashps", "")
},
- }.Check(request);
-
+ [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
+{
LOCK(cs_main);
return GetNetworkHashPS(!request.params[0].isNull() ? request.params[0].get_int() : 120, !request.params[1].isNull() ? request.params[1].get_int() : -1);
+},
+ };
}
static bool GenerateBlock(ChainstateManager& chainman, CBlock& block, uint64_t& max_tries, unsigned int& extra_nonce, uint256& block_hash)
@@ -200,9 +202,9 @@ static bool getScriptFromDescriptor(const std::string& descriptor, CScript& scri
}
}
-static UniValue generatetodescriptor(const JSONRPCRequest& request)
+static RPCHelpMan generatetodescriptor()
{
- RPCHelpMan{
+ return RPCHelpMan{
"generatetodescriptor",
"\nMine blocks immediately to a specified descriptor (before the RPC call returns)\n",
{
@@ -218,9 +220,8 @@ static UniValue generatetodescriptor(const JSONRPCRequest& request)
},
RPCExamples{
"\nGenerate 11 blocks to mydesc\n" + HelpExampleCli("generatetodescriptor", "11 \"mydesc\"")},
- }
- .Check(request);
-
+ [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
+{
const int num_blocks{request.params[0].get_int()};
const uint64_t max_tries{request.params[2].isNull() ? DEFAULT_MAX_TRIES : request.params[2].get_int()};
@@ -234,11 +235,25 @@ static UniValue generatetodescriptor(const JSONRPCRequest& request)
ChainstateManager& chainman = EnsureChainman(request.context);
return generateBlocks(chainman, mempool, coinbase_script, num_blocks, max_tries);
+},
+ };
+}
+
+static RPCHelpMan generate()
+{
+ return RPCHelpMan{"generate", "has been replaced by the -generate cli option. Refer to -help for more information.", {}, {}, RPCExamples{""}, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue {
+
+ if (request.fHelp) {
+ throw std::runtime_error(self.ToString());
+ } else {
+ throw JSONRPCError(RPC_METHOD_NOT_FOUND, self.ToString());
+ }
+ }};
}
-static UniValue generatetoaddress(const JSONRPCRequest& request)
+static RPCHelpMan generatetoaddress()
{
- RPCHelpMan{"generatetoaddress",
+ return RPCHelpMan{"generatetoaddress",
"\nMine blocks immediately to a specified address (before the RPC call returns)\n",
{
{"nblocks", RPCArg::Type::NUM, RPCArg::Optional::NO, "How many blocks are generated immediately."},
@@ -256,8 +271,8 @@ static UniValue generatetoaddress(const JSONRPCRequest& request)
+ "If you are using the " PACKAGE_NAME " wallet, you can get a new address to send the newly generated bitcoin to with:\n"
+ HelpExampleCli("getnewaddress", "")
},
- }.Check(request);
-
+ [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
+{
const int num_blocks{request.params[0].get_int()};
const uint64_t max_tries{request.params[2].isNull() ? DEFAULT_MAX_TRIES : request.params[2].get_int()};
@@ -272,11 +287,13 @@ static UniValue generatetoaddress(const JSONRPCRequest& request)
CScript coinbase_script = GetScriptForDestination(destination);
return generateBlocks(chainman, mempool, coinbase_script, num_blocks, max_tries);
+},
+ };
}
-static UniValue generateblock(const JSONRPCRequest& request)
+static RPCHelpMan generateblock()
{
- RPCHelpMan{"generateblock",
+ return RPCHelpMan{"generateblock",
"\nMine a block with a set of ordered transactions immediately to a specified address or descriptor (before the RPC call returns)\n",
{
{"output", RPCArg::Type::STR, RPCArg::Optional::NO, "The address or descriptor to send the newly generated bitcoin to."},
@@ -298,8 +315,8 @@ static UniValue generateblock(const JSONRPCRequest& request)
"\nGenerate a block to myaddress, with txs rawtx and mempool_txid\n"
+ HelpExampleCli("generateblock", R"("myaddress" '["rawtx", "mempool_txid"]')")
},
- }.Check(request);
-
+ [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
+{
const auto address_or_descriptor = request.params[0].get_str();
CScript coinbase_script;
std::string error;
@@ -335,7 +352,7 @@ static UniValue generateblock(const JSONRPCRequest& request)
txs.push_back(MakeTransactionRef(std::move(mtx)));
} else {
- throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("Transaction decode failed for %s", str));
+ throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("Transaction decode failed for %s. Make sure the tx has at least one input.", str));
}
}
@@ -379,11 +396,13 @@ static UniValue generateblock(const JSONRPCRequest& request)
UniValue obj(UniValue::VOBJ);
obj.pushKV("hash", block_hash.GetHex());
return obj;
+},
+ };
}
-static UniValue getmininginfo(const JSONRPCRequest& request)
+static RPCHelpMan getmininginfo()
{
- RPCHelpMan{"getmininginfo",
+ return RPCHelpMan{"getmininginfo",
"\nReturns a json object containing mining-related information.",
{},
RPCResult{
@@ -402,8 +421,8 @@ static UniValue getmininginfo(const JSONRPCRequest& request)
HelpExampleCli("getmininginfo", "")
+ HelpExampleRpc("getmininginfo", "")
},
- }.Check(request);
-
+ [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
+{
LOCK(cs_main);
const CTxMemPool& mempool = EnsureMemPool(request.context);
@@ -412,18 +431,20 @@ static UniValue getmininginfo(const JSONRPCRequest& request)
if (BlockAssembler::m_last_block_weight) obj.pushKV("currentblockweight", *BlockAssembler::m_last_block_weight);
if (BlockAssembler::m_last_block_num_txs) obj.pushKV("currentblocktx", *BlockAssembler::m_last_block_num_txs);
obj.pushKV("difficulty", (double)GetDifficulty(::ChainActive().Tip()));
- obj.pushKV("networkhashps", getnetworkhashps(request));
+ obj.pushKV("networkhashps", getnetworkhashps().HandleRequest(request));
obj.pushKV("pooledtx", (uint64_t)mempool.size());
obj.pushKV("chain", Params().NetworkIDString());
obj.pushKV("warnings", GetWarnings(false).original);
return obj;
+},
+ };
}
// NOTE: Unlike wallet RPC (which use BTC values), mining RPCs follow GBT (BIP 22) in using satoshi amounts
-static UniValue prioritisetransaction(const JSONRPCRequest& request)
+static RPCHelpMan prioritisetransaction()
{
- RPCHelpMan{"prioritisetransaction",
+ return RPCHelpMan{"prioritisetransaction",
"Accepts the transaction into mined blocks at a higher (or lower) priority\n",
{
{"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id."},
@@ -440,8 +461,8 @@ static UniValue prioritisetransaction(const JSONRPCRequest& request)
HelpExampleCli("prioritisetransaction", "\"txid\" 0.0 10000")
+ HelpExampleRpc("prioritisetransaction", "\"txid\", 0.0, 10000")
},
- }.Check(request);
-
+ [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
+{
LOCK(cs_main);
uint256 hash(ParseHashV(request.params[0], "txid"));
@@ -453,6 +474,8 @@ static UniValue prioritisetransaction(const JSONRPCRequest& request)
EnsureMemPool(request.context).PrioritiseTransaction(hash, nAmount);
return true;
+},
+ };
}
@@ -484,9 +507,9 @@ static std::string gbt_vb_name(const Consensus::DeploymentPos pos) {
return s;
}
-static UniValue getblocktemplate(const JSONRPCRequest& request)
+static RPCHelpMan getblocktemplate()
{
- RPCHelpMan{"getblocktemplate",
+ return RPCHelpMan{"getblocktemplate",
"\nIf the request parameters include a 'mode' key, that is used to explicitly select between the default 'template' request or a 'proposal'.\n"
"It returns data needed to construct a block to work on.\n"
"For full specification, see BIPs 22, 23, 9, and 145:\n"
@@ -500,12 +523,13 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
{"mode", RPCArg::Type::STR, /* treat as named arg */ RPCArg::Optional::OMITTED_NAMED_ARG, "This must be set to \"template\", \"proposal\" (see BIP 23), or omitted"},
{"capabilities", RPCArg::Type::ARR, /* treat as named arg */ RPCArg::Optional::OMITTED_NAMED_ARG, "A list of strings",
{
- {"support", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "client side supported feature, 'longpoll', 'coinbasetxn', 'coinbasevalue', 'proposal', 'serverlist', 'workid'"},
+ {"str", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "client side supported feature, 'longpoll', 'coinbasevalue', 'proposal', 'serverlist', 'workid'"},
},
},
{"rules", RPCArg::Type::ARR, RPCArg::Optional::NO, "A list of strings",
{
- {"support", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "client side supported softfork deployment"},
+ {"segwit", RPCArg::Type::STR, RPCArg::Optional::NO, "(literal) indicates client side segwit support"},
+ {"str", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "other client side supported softfork deployment"},
},
},
},
@@ -517,7 +541,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
{RPCResult::Type::NUM, "version", "The preferred block version"},
{RPCResult::Type::ARR, "rules", "specific block rules that are to be enforced",
{
- {RPCResult::Type::STR, "", "rulename"},
+ {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",
{
@@ -525,7 +549,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
}},
{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, "", "contents of non-coinbase transactions that should be included in the next block",
+ {RPCResult::Type::ARR, "transactions", "contents of non-coinbase transactions that should be included in the next block",
{
{RPCResult::Type::OBJ, "", "",
{
@@ -541,15 +565,12 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
{RPCResult::Type::NUM, "weight", "total transaction weight, as counted for purposes of block limits"},
}},
}},
- {RPCResult::Type::OBJ, "coinbaseaux", "data that should be included in the coinbase's scriptSig content",
+ {RPCResult::Type::OBJ_DYN, "coinbaseaux", "data that should be included in the coinbase's scriptSig content",
{
- {RPCResult::Type::ELISION, "", ""},
+ {RPCResult::Type::STR_HEX, "key", "values must be in the coinbase (keys may be ignored)"},
}},
{RPCResult::Type::NUM, "coinbasevalue", "maximum allowable input to coinbase transaction, including the generation award and transaction fees (in satoshis)"},
- {RPCResult::Type::OBJ, "coinbasetxn", "information for coinbase transaction",
- {
- {RPCResult::Type::ELISION, "", ""},
- }},
+ {RPCResult::Type::STR, "longpollid", "an id to include with a request to longpoll on an update to this template"},
{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",
@@ -563,13 +584,14 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
{RPCResult::Type::NUM_TIME, "curtime", "current timestamp in " + UNIX_EPOCH_TIME},
{RPCResult::Type::STR, "bits", "compressed target of next block"},
{RPCResult::Type::NUM, "height", "The height of the next block"},
+ {RPCResult::Type::STR, "default_witness_commitment", /* optional */ true, "a valid witness commitment for the unmodified block template"}
}},
RPCExamples{
HelpExampleCli("getblocktemplate", "'{\"rules\": [\"segwit\"]}'")
+ HelpExampleRpc("getblocktemplate", "{\"rules\": [\"segwit\"]}")
},
- }.Check(request);
-
+ [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
+{
LOCK(cs_main);
std::string strMode = "template";
@@ -877,6 +899,8 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
}
return result;
+},
+ };
}
class submitblock_StateCatcher final : public CValidationInterface
@@ -897,10 +921,10 @@ protected:
}
};
-static UniValue submitblock(const JSONRPCRequest& request)
+static RPCHelpMan submitblock()
{
// We allow 2 arguments for compliance with BIP22. Argument 2 is ignored.
- RPCHelpMan{"submitblock",
+ return RPCHelpMan{"submitblock",
"\nAttempts to submit new block to network.\n"
"See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n",
{
@@ -912,8 +936,8 @@ static UniValue submitblock(const JSONRPCRequest& request)
HelpExampleCli("submitblock", "\"mydata\"")
+ HelpExampleRpc("submitblock", "\"mydata\"")
},
- }.Check(request);
-
+ [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
+{
std::shared_ptr<CBlock> blockptr = std::make_shared<CBlock>();
CBlock& block = *blockptr;
if (!DecodeHexBlk(block, request.params[0].get_str())) {
@@ -958,11 +982,13 @@ static UniValue submitblock(const JSONRPCRequest& request)
return "inconclusive";
}
return BIP22ValidationResult(sc->state);
+},
+ };
}
-static UniValue submitheader(const JSONRPCRequest& request)
+static RPCHelpMan submitheader()
{
- RPCHelpMan{"submitheader",
+ return RPCHelpMan{"submitheader",
"\nDecode the given hexdata as a header and submit it as a candidate chain tip if valid."
"\nThrows when the header is invalid.\n",
{
@@ -974,8 +1000,8 @@ static UniValue submitheader(const JSONRPCRequest& request)
HelpExampleCli("submitheader", "\"aabbcc\"") +
HelpExampleRpc("submitheader", "\"aabbcc\"")
},
- }.Check(request);
-
+ [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
+{
CBlockHeader h;
if (!DecodeHexBlockHeader(h, request.params[0].get_str())) {
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block header decode failed");
@@ -994,11 +1020,13 @@ static UniValue submitheader(const JSONRPCRequest& request)
throw JSONRPCError(RPC_VERIFY_ERROR, state.ToString());
}
throw JSONRPCError(RPC_VERIFY_ERROR, state.GetRejectReason());
+},
+ };
}
-static UniValue estimatesmartfee(const JSONRPCRequest& request)
+static RPCHelpMan estimatesmartfee()
{
- RPCHelpMan{"estimatesmartfee",
+ return RPCHelpMan{"estimatesmartfee",
"\nEstimates the approximate fee per kilobyte needed for a transaction to begin\n"
"confirmation within conf_target blocks if possible and return the number of blocks\n"
"for which the estimate is valid. Uses virtual transaction size as defined\n"
@@ -1019,7 +1047,7 @@ static UniValue estimatesmartfee(const JSONRPCRequest& request)
RPCResult::Type::OBJ, "", "",
{
{RPCResult::Type::NUM, "feerate", /* optional */ true, "estimate fee rate in " + CURRENCY_UNIT + "/kB (only present if no errors were encountered)"},
- {RPCResult::Type::ARR, "errors", "Errors encountered during processing",
+ {RPCResult::Type::ARR, "errors", /* optional */ true, "Errors encountered during processing (if there are any)",
{
{RPCResult::Type::STR, "", "error"},
}},
@@ -1032,8 +1060,8 @@ static UniValue estimatesmartfee(const JSONRPCRequest& request)
RPCExamples{
HelpExampleCli("estimatesmartfee", "6")
},
- }.Check(request);
-
+ [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
+{
RPCTypeCheck(request.params, {UniValue::VNUM, UniValue::VSTR});
RPCTypeCheckArgument(request.params[0], UniValue::VNUM);
unsigned int max_target = ::feeEstimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
@@ -1059,11 +1087,13 @@ static UniValue estimatesmartfee(const JSONRPCRequest& request)
}
result.pushKV("blocks", feeCalc.returnedTarget);
return result;
+},
+ };
}
-static UniValue estimaterawfee(const JSONRPCRequest& request)
+static RPCHelpMan estimaterawfee()
{
- RPCHelpMan{"estimaterawfee",
+ return RPCHelpMan{"estimaterawfee",
"\nWARNING: This interface is unstable and may disappear or change!\n"
"\nWARNING: This is an advanced API call that is tightly coupled to the specific\n"
" implementation of fee estimation. The parameters it can be called with\n"
@@ -1098,7 +1128,7 @@ static UniValue estimaterawfee(const JSONRPCRequest& request)
{
{RPCResult::Type::ELISION, "", ""},
}},
- {RPCResult::Type::ARR, "errors", /* optional */ true, "Errors encountered during processing",
+ {RPCResult::Type::ARR, "errors", /* optional */ true, "Errors encountered during processing (if there are any)",
{
{RPCResult::Type::STR, "error", ""},
}},
@@ -1115,8 +1145,8 @@ static UniValue estimaterawfee(const JSONRPCRequest& request)
RPCExamples{
HelpExampleCli("estimaterawfee", "6 0.9")
},
- }.Check(request);
-
+ [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
+{
RPCTypeCheck(request.params, {UniValue::VNUM, UniValue::VNUM}, true);
RPCTypeCheckArgument(request.params[0], UniValue::VNUM);
unsigned int max_target = ::feeEstimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
@@ -1175,6 +1205,8 @@ static UniValue estimaterawfee(const JSONRPCRequest& request)
result.pushKV(StringForFeeEstimateHorizon(horizon), horizon_result);
}
return result;
+},
+ };
}
void RegisterMiningRPCCommands(CRPCTable &t)
@@ -1198,9 +1230,10 @@ static const CRPCCommand commands[] =
{ "util", "estimatesmartfee", &estimatesmartfee, {"conf_target", "estimate_mode"} },
{ "hidden", "estimaterawfee", &estimaterawfee, {"conf_target", "threshold"} },
+ { "hidden", "generate", &generate, {} },
};
// clang-format on
-
- for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
- t.appendCommand(commands[vcidx].name, &commands[vcidx]);
+ for (const auto& c : commands) {
+ t.appendCommand(c.name, &c);
+ }
}