mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-11 14:38:29 +01:00
Merge #16240: JSONRPCRequest-aware RPCHelpMan
b6fb617aaarpc: switch to using RPCHelpMan.Check() (Karl-Johan Alm)c7a9fc234fMake the RPCHelpMan aware of JSONRPCRequest and add Check() helper (Karl-Johan Alm)5c5e32bbe3rpc: migrate JSONRPCRequest functionality into request.cpp (Karl-Johan Alm)0ab8ba1ac6rpc: fix RPC help requirements for getblocktemplate (Karl-Johan Alm) Pull request description: Every single RPC call has a helper-section at the start, which throws a help string if the user asks for help or if the user provided too few/many arguments. ```C++ const RPCHelpMan help{...}; if (request.fHelp || !help.IsValidNumArgs(request.params.size())) { throw std::runtime_error(help.ToString()); } ``` or (older version) ```C++ if (request.fHelp || request.params.size() < min || request.params.size() > max) throw std::runtime_error( RPCHelpMan{...}.ToString() ); ``` It seems like an obvious improvement, and less copy-pasting, to make `RPCHelpMan` aware of `JSONRPCRequest`, and to let it handle the checks instead. Both of the above become ```C++ RPCHelpMan{...}.Check(request); ``` which means we save roughly 3 lines per RPC command, and the `RPCHelpMan` instance is never referenced afterwards, so the approach is a tiny fraction cleaner. This is a complete update, sans a few special case locations that had special rules. 623 lines turn into 284 (which includes the addition to `RPCHelpMan`). ACKs for top commit: laanwj: code rview and lightly tested ACKb6fb617aaaMarcoFalke: ACKb6fb617aaa, looked at the diff, verified move-only where applicable Tree-SHA512: eb73f47f812512905b852e313281d1c8df803db40a6188aa39d5a7586631664db6764491152a8a96769946c796dc56d38c6e3a66ddd06ba3fb9d20050e6274e1
This commit is contained in:
@@ -71,7 +71,7 @@ static void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue&
|
||||
|
||||
static UniValue getrawtransaction(const JSONRPCRequest& request)
|
||||
{
|
||||
const RPCHelpMan help{
|
||||
RPCHelpMan{
|
||||
"getrawtransaction",
|
||||
"\nReturn the raw transaction data.\n"
|
||||
|
||||
@@ -149,11 +149,7 @@ static UniValue getrawtransaction(const JSONRPCRequest& request)
|
||||
+ HelpExampleCli("getrawtransaction", "\"mytxid\" false \"myblockhash\"")
|
||||
+ HelpExampleCli("getrawtransaction", "\"mytxid\" true \"myblockhash\"")
|
||||
},
|
||||
};
|
||||
|
||||
if (request.fHelp || !help.IsValidNumArgs(request.params.size())) {
|
||||
throw std::runtime_error(help.ToString());
|
||||
}
|
||||
}.Check(request);
|
||||
|
||||
bool in_active_chain = true;
|
||||
uint256 hash = ParseHashV(request.params[0], "parameter 1");
|
||||
@@ -217,8 +213,6 @@ static UniValue getrawtransaction(const JSONRPCRequest& request)
|
||||
|
||||
static UniValue gettxoutproof(const JSONRPCRequest& request)
|
||||
{
|
||||
if (request.fHelp || (request.params.size() != 1 && request.params.size() != 2))
|
||||
throw std::runtime_error(
|
||||
RPCHelpMan{"gettxoutproof",
|
||||
"\nReturns a hex-encoded proof that \"txid\" was included in a block.\n"
|
||||
"\nNOTE: By default this function only works sometimes. This is when there is an\n"
|
||||
@@ -237,8 +231,7 @@ static UniValue gettxoutproof(const JSONRPCRequest& request)
|
||||
"\"data\" (string) A string that is a serialized, hex-encoded data for the proof.\n"
|
||||
},
|
||||
RPCExamples{""},
|
||||
}.ToString()
|
||||
);
|
||||
}.Check(request);
|
||||
|
||||
std::set<uint256> setTxids;
|
||||
uint256 oneTxid;
|
||||
@@ -313,8 +306,6 @@ static UniValue gettxoutproof(const JSONRPCRequest& request)
|
||||
|
||||
static UniValue verifytxoutproof(const JSONRPCRequest& request)
|
||||
{
|
||||
if (request.fHelp || request.params.size() != 1)
|
||||
throw std::runtime_error(
|
||||
RPCHelpMan{"verifytxoutproof",
|
||||
"\nVerifies that a proof points to a transaction in a block, returning the transaction it commits to\n"
|
||||
"and throwing an RPC error if the block is not in our best chain\n",
|
||||
@@ -325,8 +316,7 @@ static UniValue verifytxoutproof(const JSONRPCRequest& request)
|
||||
"[\"txid\"] (array, strings) The txid(s) which the proof commits to, or empty array if the proof can not be validated.\n"
|
||||
},
|
||||
RPCExamples{""},
|
||||
}.ToString()
|
||||
);
|
||||
}.Check(request);
|
||||
|
||||
CDataStream ssMB(ParseHexV(request.params[0], "proof"), SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS);
|
||||
CMerkleBlock merkleBlock;
|
||||
@@ -358,8 +348,6 @@ static UniValue verifytxoutproof(const JSONRPCRequest& request)
|
||||
|
||||
static UniValue createrawtransaction(const JSONRPCRequest& request)
|
||||
{
|
||||
if (request.fHelp || request.params.size() < 2 || request.params.size() > 4) {
|
||||
throw std::runtime_error(
|
||||
RPCHelpMan{"createrawtransaction",
|
||||
"\nCreate a transaction spending the given inputs and creating new outputs.\n"
|
||||
"Outputs can be addresses or data.\n"
|
||||
@@ -408,8 +396,7 @@ static UniValue createrawtransaction(const JSONRPCRequest& request)
|
||||
+ HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"[{\\\"address\\\":0.01}]\"")
|
||||
+ HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"[{\\\"data\\\":\\\"00010203\\\"}]\"")
|
||||
},
|
||||
}.ToString());
|
||||
}
|
||||
}.Check(request);
|
||||
|
||||
RPCTypeCheck(request.params, {
|
||||
UniValue::VARR,
|
||||
@@ -426,7 +413,7 @@ static UniValue createrawtransaction(const JSONRPCRequest& request)
|
||||
|
||||
static UniValue decoderawtransaction(const JSONRPCRequest& request)
|
||||
{
|
||||
const RPCHelpMan help{"decoderawtransaction",
|
||||
RPCHelpMan{"decoderawtransaction",
|
||||
"\nReturn a JSON object representing the serialized, hex-encoded transaction.\n",
|
||||
{
|
||||
{"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction hex string"},
|
||||
@@ -483,11 +470,7 @@ static UniValue decoderawtransaction(const JSONRPCRequest& request)
|
||||
HelpExampleCli("decoderawtransaction", "\"hexstring\"")
|
||||
+ HelpExampleRpc("decoderawtransaction", "\"hexstring\"")
|
||||
},
|
||||
};
|
||||
|
||||
if (request.fHelp || !help.IsValidNumArgs(request.params.size())) {
|
||||
throw std::runtime_error(help.ToString());
|
||||
}
|
||||
}.Check(request);
|
||||
|
||||
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL});
|
||||
|
||||
@@ -518,7 +501,7 @@ static std::string GetAllOutputTypes()
|
||||
|
||||
static UniValue decodescript(const JSONRPCRequest& request)
|
||||
{
|
||||
const RPCHelpMan help{"decodescript",
|
||||
RPCHelpMan{"decodescript",
|
||||
"\nDecode a hex-encoded script.\n",
|
||||
{
|
||||
{"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hex-encoded script"},
|
||||
@@ -549,11 +532,7 @@ static UniValue decodescript(const JSONRPCRequest& request)
|
||||
HelpExampleCli("decodescript", "\"hexstring\"")
|
||||
+ HelpExampleRpc("decodescript", "\"hexstring\"")
|
||||
},
|
||||
};
|
||||
|
||||
if (request.fHelp || !help.IsValidNumArgs(request.params.size())) {
|
||||
throw std::runtime_error(help.ToString());
|
||||
}
|
||||
}.Check(request);
|
||||
|
||||
RPCTypeCheck(request.params, {UniValue::VSTR});
|
||||
|
||||
@@ -610,8 +589,6 @@ static UniValue decodescript(const JSONRPCRequest& request)
|
||||
|
||||
static UniValue combinerawtransaction(const JSONRPCRequest& request)
|
||||
{
|
||||
if (request.fHelp || request.params.size() != 1)
|
||||
throw std::runtime_error(
|
||||
RPCHelpMan{"combinerawtransaction",
|
||||
"\nCombine multiple partially signed transactions into one transaction.\n"
|
||||
"The combined transaction may be another partially signed transaction or a \n"
|
||||
@@ -629,7 +606,7 @@ static UniValue combinerawtransaction(const JSONRPCRequest& request)
|
||||
RPCExamples{
|
||||
HelpExampleCli("combinerawtransaction", "[\"myhex1\", \"myhex2\", \"myhex3\"]")
|
||||
},
|
||||
}.ToString());
|
||||
}.Check(request);
|
||||
|
||||
|
||||
UniValue txs = request.params[0].get_array();
|
||||
@@ -694,8 +671,6 @@ static UniValue combinerawtransaction(const JSONRPCRequest& request)
|
||||
|
||||
static UniValue signrawtransactionwithkey(const JSONRPCRequest& request)
|
||||
{
|
||||
if (request.fHelp || request.params.size() < 2 || request.params.size() > 4)
|
||||
throw std::runtime_error(
|
||||
RPCHelpMan{"signrawtransactionwithkey",
|
||||
"\nSign inputs for raw transaction (serialized, hex-encoded).\n"
|
||||
"The second argument is an array of base58-encoded private\n"
|
||||
@@ -752,7 +727,7 @@ static UniValue signrawtransactionwithkey(const JSONRPCRequest& request)
|
||||
HelpExampleCli("signrawtransactionwithkey", "\"myhex\" \"[\\\"key1\\\",\\\"key2\\\"]\"")
|
||||
+ HelpExampleRpc("signrawtransactionwithkey", "\"myhex\", \"[\\\"key1\\\",\\\"key2\\\"]\"")
|
||||
},
|
||||
}.ToString());
|
||||
}.Check(request);
|
||||
|
||||
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR, UniValue::VARR, UniValue::VSTR}, true);
|
||||
|
||||
@@ -784,7 +759,7 @@ static UniValue signrawtransactionwithkey(const JSONRPCRequest& request)
|
||||
|
||||
static UniValue sendrawtransaction(const JSONRPCRequest& request)
|
||||
{
|
||||
const RPCHelpMan help{"sendrawtransaction",
|
||||
RPCHelpMan{"sendrawtransaction",
|
||||
"\nSubmits raw transaction (serialized, hex-encoded) to local node and network.\n"
|
||||
"\nAlso see createrawtransaction and signrawtransactionwithkey calls.\n",
|
||||
{
|
||||
@@ -806,11 +781,7 @@ static UniValue sendrawtransaction(const JSONRPCRequest& request)
|
||||
"\nAs a JSON-RPC call\n"
|
||||
+ HelpExampleRpc("sendrawtransaction", "\"signedhex\"")
|
||||
},
|
||||
};
|
||||
|
||||
if (request.fHelp || !help.IsValidNumArgs(request.params.size())) {
|
||||
throw std::runtime_error(help.ToString());
|
||||
}
|
||||
}.Check(request);
|
||||
|
||||
RPCTypeCheck(request.params, {
|
||||
UniValue::VSTR,
|
||||
@@ -848,7 +819,7 @@ static UniValue sendrawtransaction(const JSONRPCRequest& request)
|
||||
|
||||
static UniValue testmempoolaccept(const JSONRPCRequest& request)
|
||||
{
|
||||
const RPCHelpMan help{"testmempoolaccept",
|
||||
RPCHelpMan{"testmempoolaccept",
|
||||
"\nReturns result of mempool acceptance tests indicating if raw transaction (serialized, hex-encoded) would be accepted by mempool.\n"
|
||||
"\nThis checks if the transaction violates the consensus or policy rules.\n"
|
||||
"\nSee sendrawtransaction call.\n",
|
||||
@@ -881,11 +852,7 @@ static UniValue testmempoolaccept(const JSONRPCRequest& request)
|
||||
"\nAs a JSON-RPC call\n"
|
||||
+ HelpExampleRpc("testmempoolaccept", "[\"signedhex\"]")
|
||||
},
|
||||
};
|
||||
|
||||
if (request.fHelp || !help.IsValidNumArgs(request.params.size())) {
|
||||
throw std::runtime_error(help.ToString());
|
||||
}
|
||||
}.Check(request);
|
||||
|
||||
RPCTypeCheck(request.params, {
|
||||
UniValue::VARR,
|
||||
@@ -964,8 +931,6 @@ static std::string WriteHDKeypath(std::vector<uint32_t>& keypath)
|
||||
|
||||
UniValue decodepsbt(const JSONRPCRequest& request)
|
||||
{
|
||||
if (request.fHelp || request.params.size() != 1)
|
||||
throw std::runtime_error(
|
||||
RPCHelpMan{"decodepsbt",
|
||||
"\nReturn a JSON object representing the serialized, base64-encoded partially signed Bitcoin transaction.\n",
|
||||
{
|
||||
@@ -1062,7 +1027,7 @@ UniValue decodepsbt(const JSONRPCRequest& request)
|
||||
RPCExamples{
|
||||
HelpExampleCli("decodepsbt", "\"psbt\"")
|
||||
},
|
||||
}.ToString());
|
||||
}.Check(request);
|
||||
|
||||
RPCTypeCheck(request.params, {UniValue::VSTR});
|
||||
|
||||
@@ -1239,8 +1204,6 @@ UniValue decodepsbt(const JSONRPCRequest& request)
|
||||
|
||||
UniValue combinepsbt(const JSONRPCRequest& request)
|
||||
{
|
||||
if (request.fHelp || request.params.size() != 1)
|
||||
throw std::runtime_error(
|
||||
RPCHelpMan{"combinepsbt",
|
||||
"\nCombine multiple partially signed Bitcoin transactions into one transaction.\n"
|
||||
"Implements the Combiner role.\n",
|
||||
@@ -1257,7 +1220,7 @@ UniValue combinepsbt(const JSONRPCRequest& request)
|
||||
RPCExamples{
|
||||
HelpExampleCli("combinepsbt", "[\"mybase64_1\", \"mybase64_2\", \"mybase64_3\"]")
|
||||
},
|
||||
}.ToString());
|
||||
}.Check(request);
|
||||
|
||||
RPCTypeCheck(request.params, {UniValue::VARR}, true);
|
||||
|
||||
@@ -1289,8 +1252,6 @@ UniValue combinepsbt(const JSONRPCRequest& request)
|
||||
|
||||
UniValue finalizepsbt(const JSONRPCRequest& request)
|
||||
{
|
||||
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
|
||||
throw std::runtime_error(
|
||||
RPCHelpMan{"finalizepsbt",
|
||||
"Finalize the inputs of a PSBT. If the transaction is fully signed, it will produce a\n"
|
||||
"network serialized transaction which can be broadcast with sendrawtransaction. Otherwise a PSBT will be\n"
|
||||
@@ -1312,7 +1273,7 @@ UniValue finalizepsbt(const JSONRPCRequest& request)
|
||||
RPCExamples{
|
||||
HelpExampleCli("finalizepsbt", "\"psbt\"")
|
||||
},
|
||||
}.ToString());
|
||||
}.Check(request);
|
||||
|
||||
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL}, true);
|
||||
|
||||
@@ -1348,8 +1309,6 @@ UniValue finalizepsbt(const JSONRPCRequest& request)
|
||||
|
||||
UniValue createpsbt(const JSONRPCRequest& request)
|
||||
{
|
||||
if (request.fHelp || request.params.size() < 2 || request.params.size() > 4)
|
||||
throw std::runtime_error(
|
||||
RPCHelpMan{"createpsbt",
|
||||
"\nCreates a transaction in the Partially Signed Transaction format.\n"
|
||||
"Implements the Creator role.\n",
|
||||
@@ -1392,7 +1351,7 @@ UniValue createpsbt(const JSONRPCRequest& request)
|
||||
RPCExamples{
|
||||
HelpExampleCli("createpsbt", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"")
|
||||
},
|
||||
}.ToString());
|
||||
}.Check(request);
|
||||
|
||||
|
||||
RPCTypeCheck(request.params, {
|
||||
@@ -1424,7 +1383,7 @@ UniValue createpsbt(const JSONRPCRequest& request)
|
||||
|
||||
UniValue converttopsbt(const JSONRPCRequest& request)
|
||||
{
|
||||
const RPCHelpMan help{"converttopsbt",
|
||||
RPCHelpMan{"converttopsbt",
|
||||
"\nConverts a network serialized transaction to a PSBT. This should be used only with createrawtransaction and fundrawtransaction\n"
|
||||
"createpsbt and walletcreatefundedpsbt should be used for new applications.\n",
|
||||
{
|
||||
@@ -1448,11 +1407,7 @@ UniValue converttopsbt(const JSONRPCRequest& request)
|
||||
"\nConvert the transaction to a PSBT\n"
|
||||
+ HelpExampleCli("converttopsbt", "\"rawtransaction\"")
|
||||
},
|
||||
};
|
||||
|
||||
if (request.fHelp || !help.IsValidNumArgs(request.params.size())) {
|
||||
throw std::runtime_error(help.ToString());
|
||||
}
|
||||
}.Check(request);
|
||||
|
||||
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL, UniValue::VBOOL}, true);
|
||||
|
||||
@@ -1495,8 +1450,6 @@ UniValue converttopsbt(const JSONRPCRequest& request)
|
||||
|
||||
UniValue utxoupdatepsbt(const JSONRPCRequest& request)
|
||||
{
|
||||
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) {
|
||||
throw std::runtime_error(
|
||||
RPCHelpMan{"utxoupdatepsbt",
|
||||
"\nUpdates all segwit inputs and outputs in a PSBT with data from output descriptors, the UTXO set or the mempool.\n",
|
||||
{
|
||||
@@ -1514,8 +1467,7 @@ UniValue utxoupdatepsbt(const JSONRPCRequest& request)
|
||||
},
|
||||
RPCExamples {
|
||||
HelpExampleCli("utxoupdatepsbt", "\"psbt\"")
|
||||
}}.ToString());
|
||||
}
|
||||
}}.Check(request);
|
||||
|
||||
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR}, true);
|
||||
|
||||
@@ -1585,8 +1537,6 @@ UniValue utxoupdatepsbt(const JSONRPCRequest& request)
|
||||
|
||||
UniValue joinpsbts(const JSONRPCRequest& request)
|
||||
{
|
||||
if (request.fHelp || request.params.size() != 1) {
|
||||
throw std::runtime_error(
|
||||
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",
|
||||
@@ -1601,8 +1551,7 @@ UniValue joinpsbts(const JSONRPCRequest& request)
|
||||
},
|
||||
RPCExamples {
|
||||
HelpExampleCli("joinpsbts", "\"psbt\"")
|
||||
}}.ToString());
|
||||
}
|
||||
}}.Check(request);
|
||||
|
||||
RPCTypeCheck(request.params, {UniValue::VARR}, true);
|
||||
|
||||
@@ -1659,8 +1608,6 @@ UniValue joinpsbts(const JSONRPCRequest& request)
|
||||
|
||||
UniValue analyzepsbt(const JSONRPCRequest& request)
|
||||
{
|
||||
if (request.fHelp || request.params.size() != 1) {
|
||||
throw std::runtime_error(
|
||||
RPCHelpMan{"analyzepsbt",
|
||||
"\nAnalyzes and provides information about the current status of a PSBT and its inputs\n",
|
||||
{
|
||||
@@ -1694,8 +1641,7 @@ UniValue analyzepsbt(const JSONRPCRequest& request)
|
||||
},
|
||||
RPCExamples {
|
||||
HelpExampleCli("analyzepsbt", "\"psbt\"")
|
||||
}}.ToString());
|
||||
}
|
||||
}}.Check(request);
|
||||
|
||||
RPCTypeCheck(request.params, {UniValue::VSTR});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user