Page MenuHomePhabricator

D6220.diff
No OneTemporary

D6220.diff

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

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)

Event Timeline