Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F13115420
D6220.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
16 KB
Subscribers
None
D6220.diff
View Options
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -1,5 +1,5 @@
// Copyright (c) 2010 Satoshi Nakamoto
-// Copyright (c) 2009-2016 The Bitcoin Core developers
+// Copyright (c) 2009-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -2053,100 +2053,90 @@
static UniValue getblockstats(const Config &config,
const JSONRPCRequest &request) {
- if (request.fHelp || request.params.size() < 1 ||
- request.params.size() > 4) {
- throw std::runtime_error(RPCHelpMan{
- "getblockstats",
- "\nCompute per block statistics for a given window. All "
- "amounts are in " +
- CURRENCY_UNIT +
- ".\n"
- "It won't work for some heights with pruning.\n"
- "It won't work without -txindex for utxo_size_inc, *fee or "
- "*feerate stats.\n",
- {
- {"hash_or_height",
- RPCArg::Type::NUM,
- RPCArg::Optional::NO,
- "The block hash or height of the target block",
- "",
- {"", "string or numeric"}},
- {"stats",
- RPCArg::Type::ARR,
- /* default */ "all values",
- "Values to plot (see result below)",
- {
- {"height", RPCArg::Type::STR, RPCArg::Optional::OMITTED,
- "Selected statistic"},
- {"time", RPCArg::Type::STR, RPCArg::Optional::OMITTED,
- "Selected statistic"},
- },
- "stats"},
- },
- RPCResult{
- "{ (json object)\n"
- " \"avgfee\": x.xxx, (numeric) Average fee in the "
- "block\n"
- " \"avgfeerate\": x.xxx, (numeric) Average feerate (in " +
- CURRENCY_UNIT +
- " per byte)\n"
- " \"avgtxsize\": xxxxx, (numeric) Average transaction "
- "size\n"
- " \"blockhash\": xxxxx, (string) The block hash (to "
- "check for potential reorgs)\n"
- " \"height\": xxxxx, (numeric) The height of the "
- "block\n"
- " \"ins\": xxxxx, (numeric) The number of inputs "
- "(excluding coinbase)\n"
- " \"maxfee\": xxxxx, (numeric) Maximum fee in the "
- "block\n"
- " \"maxfeerate\": xxxxx, (numeric) Maximum feerate (in " +
- CURRENCY_UNIT +
- " per byte)\n"
- " \"maxtxsize\": xxxxx, (numeric) Maximum transaction "
- "size\n"
- " \"medianfee\": x.xxx, (numeric) Truncated median fee "
- "in the block\n"
- " \"medianfeerate\": x.xxx, (numeric) Truncated median "
- "feerate (in " +
- CURRENCY_UNIT +
- " per byte)\n"
- " \"mediantime\": xxxxx, (numeric) The block median time "
- "past\n"
- " \"mediantxsize\": xxxxx, (numeric) Truncated median "
- "transaction size\n"
- " \"minfee\": x.xxx, (numeric) Minimum fee in the "
- "block\n"
- " \"minfeerate\": xx.xx, (numeric) Minimum feerate (in " +
- CURRENCY_UNIT +
- " per byte)\n"
- " \"mintxsize\": xxxxx, (numeric) Minimum transaction "
- "size\n"
- " \"outs\": xxxxx, (numeric) The number of "
- "outputs\n"
- " \"subsidy\": x.xxx, (numeric) The block subsidy\n"
- " \"time\": xxxxx, (numeric) The block time\n"
- " \"total_out\": x.xxx, (numeric) Total amount in all "
- "outputs (excluding coinbase and thus reward [ie subsidy + "
- "totalfee])\n"
- " \"total_size\": xxxxx, (numeric) Total size of all "
- "non-coinbase transactions\n"
- " \"totalfee\": x.xxx, (numeric) The fee total\n"
- " \"txs\": xxxxx, (numeric) The number of "
- "transactions (excluding coinbase)\n"
- " \"utxo_increase\": xxxxx, (numeric) The increase/decrease "
- "in the number of unspent outputs\n"
- " \"utxo_size_inc\": xxxxx, (numeric) The increase/decrease "
- "in size for the utxo index (not discounting op_return and "
- "similar)\n"
- "}\n"},
- RPCExamples{
- HelpExampleCli("getblockstats",
- "1000 '[\"minfeerate\",\"avgfeerate\"]'") +
- HelpExampleRpc("getblockstats",
- "1000 '[\"minfeerate\",\"avgfeerate\"]'")},
- }
- .ToString());
+ const RPCHelpMan help{
+ "getblockstats",
+ "\nCompute per block statistics for a given window. All amounts are "
+ "in " +
+ CURRENCY_UNIT +
+ ".\n"
+ "It won't work for some heights with pruning.\n"
+ "It won't work without -txindex for utxo_size_inc, *fee or "
+ "*feerate stats.\n",
+ {
+ {"hash_or_height",
+ RPCArg::Type::NUM,
+ RPCArg::Optional::NO,
+ "The block hash or height of the target block",
+ "",
+ {"", "string or numeric"}},
+ {"stats",
+ RPCArg::Type::ARR,
+ /* default */ "all values",
+ "Values to plot (see result below)",
+ {
+ {"height", RPCArg::Type::STR, RPCArg::Optional::OMITTED,
+ "Selected statistic"},
+ {"time", RPCArg::Type::STR, RPCArg::Optional::OMITTED,
+ "Selected statistic"},
+ },
+ "stats"},
+ },
+ RPCResult{
+ "{ (json object)\n"
+ " \"avgfee\": x.xxx, (numeric) Average fee in the block\n"
+ " \"avgfeerate\": x.xxx, (numeric) Average feerate (in " +
+ CURRENCY_UNIT +
+ " per byte)\n"
+ " \"avgtxsize\": xxxxx, (numeric) Average transaction size\n"
+ " \"blockhash\": xxxxx, (string) The block hash (to check "
+ "for potential reorgs)\n"
+ " \"height\": xxxxx, (numeric) The height of the block\n"
+ " \"ins\": xxxxx, (numeric) The number of inputs "
+ "(excluding coinbase)\n"
+ " \"maxfee\": xxxxx, (numeric) Maximum fee in the block\n"
+ " \"maxfeerate\": xxxxx, (numeric) Maximum feerate (in " +
+ CURRENCY_UNIT +
+ " per byte)\n"
+ " \"maxtxsize\": xxxxx, (numeric) Maximum transaction size\n"
+ " \"medianfee\": x.xxx, (numeric) Truncated median fee in "
+ "the block\n"
+ " \"medianfeerate\": x.xxx, (numeric) Truncated median feerate "
+ "(in " +
+ CURRENCY_UNIT +
+ " per byte)\n"
+ " \"mediantime\": xxxxx, (numeric) The block median time "
+ "past\n"
+ " \"mediantxsize\": xxxxx, (numeric) Truncated median "
+ "transaction size\n"
+ " \"minfee\": x.xxx, (numeric) Minimum fee in the block\n"
+ " \"minfeerate\": xx.xx, (numeric) Minimum feerate (in " +
+ CURRENCY_UNIT +
+ " per byte)\n"
+ " \"mintxsize\": xxxxx, (numeric) Minimum transaction size\n"
+ " \"outs\": xxxxx, (numeric) The number of outputs\n"
+ " \"subsidy\": x.xxx, (numeric) The block subsidy\n"
+ " \"time\": xxxxx, (numeric) The block time\n"
+ " \"total_out\": x.xxx, (numeric) Total amount in all "
+ "outputs (excluding coinbase and thus reward [ie subsidy + "
+ "totalfee])\n"
+ " \"total_size\": xxxxx, (numeric) Total size of all "
+ "non-coinbase transactions\n"
+ " \"totalfee\": x.xxx, (numeric) The fee total\n"
+ " \"txs\": xxxxx, (numeric) The number of "
+ "transactions (excluding coinbase)\n"
+ " \"utxo_increase\": xxxxx, (numeric) The increase/decrease in "
+ "the number of unspent outputs\n"
+ " \"utxo_size_inc\": xxxxx, (numeric) The increase/decrease in "
+ "size for the utxo index (not discounting op_return and similar)\n"
+ "}\n"},
+ RPCExamples{HelpExampleCli("getblockstats",
+ "1000 '[\"minfeerate\",\"avgfeerate\"]'") +
+ HelpExampleRpc("getblockstats",
+ "1000 '[\"minfeerate\",\"avgfeerate\"]'")},
+ };
+
+ if (request.fHelp || !help.IsValidNumArgs(request.params.size())) {
+ throw std::runtime_error(help.ToString());
}
LOCK(cs_main);
diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp
--- a/src/rpc/net.cpp
+++ b/src/rpc/net.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2009-2016 The Bitcoin Core developers
+// Copyright (c) 2009-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -650,41 +650,42 @@
}
static UniValue setban(const Config &config, const JSONRPCRequest &request) {
+ const RPCHelpMan help{
+ "setban",
+ "\nAttempts to add or remove an IP/Subnet from the "
+ "banned list.\n",
+ {
+ {"subnet", RPCArg::Type::STR, RPCArg::Optional::NO,
+ "The IP/Subnet (see getpeerinfo for nodes IP) with an optional "
+ "netmask (default is /32 = single IP)"},
+ {"command", RPCArg::Type::STR, RPCArg::Optional::NO,
+ "'add' to add an IP/Subnet to the list, 'remove' to remove an "
+ "IP/Subnet from the list"},
+ {"bantime", RPCArg::Type::NUM, /* default */ "0",
+ "time in seconds how long (or until when if [absolute] is set) "
+ "the IP is banned (0 or empty means using the default time of 24h "
+ "which can also be overwritten by the -bantime startup argument)"},
+ {"absolute", RPCArg::Type::BOOL, /* default */ "false",
+ "If set, the bantime must be an absolute timestamp in seconds "
+ "since epoch (Jan 1 1970 GMT)"},
+ },
+ RPCResults{},
+ RPCExamples{
+ HelpExampleCli("setban", "\"192.168.0.6\" \"add\" 86400") +
+ HelpExampleCli("setban", "\"192.168.0.0/24\" \"add\"") +
+ HelpExampleRpc("setban", "\"192.168.0.6\", \"add\", 86400")},
+ };
+
std::string strCommand;
if (!request.params[1].isNull()) {
strCommand = request.params[1].get_str();
}
- if (request.fHelp || request.params.size() < 2 ||
+ if (request.fHelp || !help.IsValidNumArgs(request.params.size()) ||
(strCommand != "add" && strCommand != "remove")) {
- throw std::runtime_error(RPCHelpMan{
- "setban",
- "\nAttempts to add or remove an IP/Subnet from the "
- "banned list.\n",
- {
- {"subnet", RPCArg::Type::STR, RPCArg::Optional::NO,
- "The IP/Subnet (see getpeerinfo for nodes IP) with an "
- "optional netmask (default is /32 = single IP)"},
- {"command", RPCArg::Type::STR, RPCArg::Optional::NO,
- "'add' to add an IP/Subnet to the list, 'remove' to "
- "remove an IP/Subnet from the list"},
- {"bantime", RPCArg::Type::NUM, /* default */ "0",
- "time in seconds how long (or until when if [absolute] is "
- "set) the IP is banned (0 or empty means using the default "
- "time of 24h which can also be overwritten by the -bantime "
- "startup argument)"},
- {"absolute", RPCArg::Type::BOOL, /* default */ "false",
- "If set, the bantime must be an absolute timestamp in seconds "
- "since epoch (Jan 1 1970 GMT)"},
- },
- RPCResults{},
- RPCExamples{
- HelpExampleCli("setban", "\"192.168.0.6\" \"add\" 86400") +
- HelpExampleCli("setban", "\"192.168.0.0/24\" \"add\"") +
- HelpExampleRpc("setban", "\"192.168.0.6\", \"add\", 86400")},
- }
- .ToString());
+ throw std::runtime_error(help.ToString());
}
+
if (!g_banman) {
throw JSONRPCError(RPC_DATABASE_ERROR,
"Error: Ban database not loaded");
diff --git a/src/rpc/util.h b/src/rpc/util.h
--- a/src/rpc/util.h
+++ b/src/rpc/util.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2017 The Bitcoin Core developers
+// Copyright (c) 2017-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -109,7 +109,7 @@
/** Required arg */
NO,
/**
- * Optinal arg that is a named argument and has a default value of
+ * Optional arg that is a named argument and has a default value of
* `null`. When possible, the default value should be specified.
*/
OMITTED_NAMED_ARG,
@@ -163,6 +163,8 @@
CHECK_NONFATAL(type == Type::ARR || type == Type::OBJ);
}
+ bool IsOptional() const;
+
/**
* Return the type string of the argument.
* Set oneline to allow it to be overridden by a custom oneline type string
@@ -226,6 +228,8 @@
RPCExamples examples);
std::string ToString() const;
+ /** If the supplied number of args is neither too small nor too high */
+ bool IsValidNumArgs(size_t num_args) const;
private:
const std::string m_name;
diff --git a/src/rpc/util.cpp b/src/rpc/util.cpp
--- a/src/rpc/util.cpp
+++ b/src/rpc/util.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2017 The Bitcoin Core developers
+// Copyright (c) 2017-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -432,6 +432,16 @@
return m_examples.empty() ? m_examples : "\nExamples:\n" + m_examples;
}
+bool RPCHelpMan::IsValidNumArgs(size_t num_args) const {
+ size_t num_required_args = 0;
+ for (size_t n = m_args.size(); n > 0; --n) {
+ if (!m_args.at(n - 1).IsOptional()) {
+ num_required_args = n;
+ break;
+ }
+ }
+ return num_required_args <= num_args && num_args <= m_args.size();
+}
std::string RPCHelpMan::ToString() const {
std::string ret;
@@ -439,13 +449,7 @@
ret += m_name;
bool was_optional{false};
for (const auto &arg : m_args) {
- bool optional;
- if (arg.m_fallback.which() == 1) {
- optional = true;
- } else {
- optional = RPCArg::Optional::NO !=
- boost::get<RPCArg::Optional>(arg.m_fallback);
- }
+ const bool optional = arg.IsOptional();
ret += " ";
if (optional) {
if (!was_optional) {
@@ -498,6 +502,14 @@
return ret;
}
+bool RPCArg::IsOptional() const {
+ if (m_fallback.which() == 1) {
+ return true;
+ } else {
+ return RPCArg::Optional::NO != boost::get<RPCArg::Optional>(m_fallback);
+ }
+}
+
std::string RPCArg::ToDescriptionString() const {
std::string ret;
ret += "(";
diff --git a/test/functional/rpc_getblockstats.py b/test/functional/rpc_getblockstats.py
--- a/test/functional/rpc_getblockstats.py
+++ b/test/functional/rpc_getblockstats.py
@@ -201,6 +201,17 @@
assert_raises_rpc_error(-5, 'Block not found', self.nodes[0].getblockstats,
hash_or_height='000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f')
+ # Invalid number of args
+ assert_raises_rpc_error(-1,
+ 'getblockstats hash_or_height ( stats )',
+ self.nodes[0].getblockstats,
+ '00',
+ 1,
+ 2)
+ assert_raises_rpc_error(-1,
+ 'getblockstats hash_or_height ( stats )',
+ self.nodes[0].getblockstats)
+
if __name__ == '__main__':
GetblockstatsTest().main()
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Mar 1, 11:04 (16 h, 3 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5187479
Default Alt Text
D6220.diff (16 KB)
Attached To
D6220: rpc: Actually throw help when passed invalid number of params
Event Timeline
Log In to Comment