0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-02-02 09:46:52 -05:00

Merge bitcoin/bitcoin#26074: refactor: Set RPCArg options with designated initializers

fa2c72dda0 rpc: Set RPCArg options with designated initializers (MacroFake)

Pull request description:

  For optional constructor arguments, use a new struct. This comes with two benefits:
  * Earlier unused optional arguments can be omitted
  * Designated initializers can be used

ACKs for top commit:
  stickies-v:
    re-ACK fa2c72dda0

Tree-SHA512: 2a0619548187cc7437fee2466ac4780746490622f202659f53641be01bc2a1fea4416d1a77f3e963bf7c4cce62899b61fab0b9683440cf82f68be44f63826658
This commit is contained in:
MacroFake 2022-09-30 10:03:27 +02:00
commit 33eef562a3
No known key found for this signature in database
GPG key ID: CE2B75697E69A548
8 changed files with 47 additions and 49 deletions

View file

@ -856,7 +856,7 @@ static RPCHelpMan gettxoutsetinfo()
"Note this call may take some time if you are not using coinstatsindex.\n",
{
{"hash_type", RPCArg::Type::STR, RPCArg::Default{"hash_serialized_2"}, "Which UTXO set hash should be calculated. Options: 'hash_serialized_2' (the legacy algorithm), 'muhash', 'none'."},
{"hash_or_height", RPCArg::Type::NUM, RPCArg::DefaultHint{"the current best block"}, "The block hash or height of the target height (only available with coinstatsindex).", "", {"", "string or numeric"}},
{"hash_or_height", RPCArg::Type::NUM, RPCArg::DefaultHint{"the current best block"}, "The block hash or height of the target height (only available with coinstatsindex).", RPCArgOptions{.type_str={"", "string or numeric"}}},
{"use_index", RPCArg::Type::BOOL, RPCArg::Default{true}, "Use coinstatsindex, if available."},
},
RPCResult{
@ -1726,13 +1726,13 @@ static RPCHelpMan getblockstats()
"\nCompute per block statistics for a given window. All amounts are in satoshis.\n"
"It won't work for some heights with pruning.\n",
{
{"hash_or_height", RPCArg::Type::NUM, RPCArg::Optional::NO, "The block hash or height of the target block", "", {"", "string or numeric"}},
{"hash_or_height", RPCArg::Type::NUM, RPCArg::Optional::NO, "The block hash or height of the target block", RPCArgOptions{.type_str={"", "string or numeric"}}},
{"stats", RPCArg::Type::ARR, RPCArg::DefaultHint{"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"},
RPCArgOptions{.oneline_description="stats"}},
},
RPCResult{
RPCResult::Type::OBJ, "", "",
@ -2052,7 +2052,7 @@ static RPCHelpMan scantxoutset()
{"range", RPCArg::Type::RANGE, RPCArg::Default{1000}, "The range of HD chain indexes to explore (either end or [begin,end])"},
}},
},
"[scanobjects,...]"},
RPCArgOptions{.oneline_description="[scanobjects,...]"}},
},
{
RPCResult{"when action=='start'; only returns after scan completes", RPCResult::Type::OBJ, "", "", {

View file

@ -524,7 +524,7 @@ static RPCHelpMan getblocktemplate()
{"str", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "other client side supported softfork deployment"},
}},
},
"\"template_request\""},
RPCArgOptions{.oneline_description="\"template_request\""}},
},
{
RPCResult{"If the proposal was accepted with mode=='proposal'", RPCResult::Type::NONE, "", ""},

View file

@ -168,7 +168,7 @@ static RPCHelpMan stop()
// to the client (intended for testing)
"\nRequest a graceful shutdown of " PACKAGE_NAME ".",
{
{"wait", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "how long to wait in ms", "", {}, /*hidden=*/true},
{"wait", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "how long to wait in ms", RPCArgOptions{.hidden=true}},
},
RPCResult{RPCResult::Type::STR, "", "A string with the content '" + RESULT + "'"},
RPCExamples{""},

View file

@ -418,8 +418,8 @@ struct Sections {
case RPCArg::Type::BOOL: {
if (outer_type == OuterType::NONE) return; // Nothing more to do for non-recursive types on first recursion
auto left = indent;
if (arg.m_type_str.size() != 0 && push_name) {
left += "\"" + arg.GetName() + "\": " + arg.m_type_str.at(0);
if (arg.m_opts.type_str.size() != 0 && push_name) {
left += "\"" + arg.GetName() + "\": " + arg.m_opts.type_str.at(0);
} else {
left += push_name ? arg.ToStringObj(/*oneline=*/false) : arg.ToString(/*oneline=*/false);
}
@ -618,7 +618,7 @@ std::string RPCHelpMan::ToString() const
ret += m_name;
bool was_optional{false};
for (const auto& arg : m_args) {
if (arg.m_hidden) break; // Any arg that follows is also hidden
if (arg.m_opts.hidden) break; // Any arg that follows is also hidden
const bool optional = arg.IsOptional();
ret += " ";
if (optional) {
@ -639,7 +639,7 @@ std::string RPCHelpMan::ToString() const
Sections sections;
for (size_t i{0}; i < m_args.size(); ++i) {
const auto& arg = m_args.at(i);
if (arg.m_hidden) break; // Any arg that follows is also hidden
if (arg.m_opts.hidden) break; // Any arg that follows is also hidden
if (i == 0) ret += "\nArguments:\n";
@ -704,8 +704,8 @@ std::string RPCArg::ToDescriptionString() const
{
std::string ret;
ret += "(";
if (m_type_str.size() != 0) {
ret += m_type_str.at(1);
if (m_opts.type_str.size() != 0) {
ret += m_opts.type_str.at(1);
} else {
switch (m_type) {
case Type::STR_HEX:
@ -991,7 +991,7 @@ std::string RPCArg::ToStringObj(const bool oneline) const
std::string RPCArg::ToString(const bool oneline) const
{
if (oneline && !m_oneline_description.empty()) return m_oneline_description;
if (oneline && !m_opts.oneline_description.empty()) return m_opts.oneline_description;
switch (m_type) {
case Type::STR_HEX:

View file

@ -137,6 +137,12 @@ enum class OuterType {
NONE, // Only set on first recursion
};
struct RPCArgOptions {
std::string oneline_description{}; //!< Should be empty unless it is supposed to override the auto-generated summary line
std::vector<std::string> type_str{}; //!< Should be empty unless it is supposed to override the auto-generated type strings. Vector length is either 0 or 2, m_opts.type_str.at(0) will override the type of the value in a key-value pair, m_opts.type_str.at(1) will override the type in the argument description.
bool hidden{false}; //!< For testing only
};
struct RPCArg {
enum class Type {
OBJ,
@ -169,30 +175,25 @@ struct RPCArg {
using DefaultHint = std::string;
using Default = UniValue;
using Fallback = std::variant<Optional, /* hint for default value */ DefaultHint, /* default constant value */ Default>;
const std::string m_names; //!< The name of the arg (can be empty for inner args, can contain multiple aliases separated by | for named request arguments)
const Type m_type;
const bool m_hidden;
const std::vector<RPCArg> m_inner; //!< Only used for arrays or dicts
const Fallback m_fallback;
const std::string m_description;
const std::string m_oneline_description; //!< Should be empty unless it is supposed to override the auto-generated summary line
const std::vector<std::string> m_type_str; //!< Should be empty unless it is supposed to override the auto-generated type strings. Vector length is either 0 or 2, m_type_str.at(0) will override the type of the value in a key-value pair, m_type_str.at(1) will override the type in the argument description.
const RPCArgOptions m_opts;
RPCArg(
const std::string name,
const Type type,
const Fallback fallback,
const std::string description,
const std::string oneline_description = "",
const std::vector<std::string> type_str = {},
const bool hidden = false)
RPCArgOptions opts = {})
: m_names{std::move(name)},
m_type{std::move(type)},
m_hidden{hidden},
m_fallback{std::move(fallback)},
m_description{std::move(description)},
m_oneline_description{std::move(oneline_description)},
m_type_str{std::move(type_str)}
m_opts{std::move(opts)}
{
CHECK_NONFATAL(type != Type::ARR && type != Type::OBJ && type != Type::OBJ_USER_KEYS);
}
@ -203,16 +204,13 @@ struct RPCArg {
const Fallback fallback,
const std::string description,
const std::vector<RPCArg> inner,
const std::string oneline_description = "",
const std::vector<std::string> type_str = {})
RPCArgOptions opts = {})
: m_names{std::move(name)},
m_type{std::move(type)},
m_hidden{false},
m_inner{std::move(inner)},
m_fallback{std::move(fallback)},
m_description{std::move(description)},
m_oneline_description{std::move(oneline_description)},
m_type_str{std::move(type_str)}
m_opts{std::move(opts)}
{
CHECK_NONFATAL(type == Type::ARR || type == Type::OBJ || type == Type::OBJ_USER_KEYS);
}
@ -227,7 +225,7 @@ struct RPCArg {
/**
* Return the type string of the argument.
* Set oneline to allow it to be overridden by a custom oneline type string (m_oneline_description).
* Set oneline to allow it to be overridden by a custom oneline type string (m_opts.oneline_description).
*/
std::string ToString(bool oneline) const;
/**

View file

@ -1266,15 +1266,15 @@ RPCHelpMan importmulti()
{
{"desc", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "Descriptor to import. If using descriptor, do not also provide address/scriptPubKey, scripts, or pubkeys"},
{"scriptPubKey", RPCArg::Type::STR, RPCArg::Optional::NO, "Type of scriptPubKey (string for script, json for address). Should not be provided if using a descriptor",
/*oneline_description=*/"", {"\"<script>\" | { \"address\":\"<address>\" }", "string / json"}
RPCArgOptions{.type_str={"\"<script>\" | { \"address\":\"<address>\" }", "string / json"}}
},
{"timestamp", RPCArg::Type::NUM, RPCArg::Optional::NO, "Creation time of the key expressed in " + UNIX_EPOCH_TIME + ",\n"
" or the string \"now\" to substitute the current synced blockchain time. The timestamp of the oldest\n"
" key will determine how far back blockchain rescans need to begin for missing wallet transactions.\n"
" \"now\" can be specified to bypass scanning, for keys which are known to never have been used, and\n"
" 0 can be specified to scan the entire blockchain. Blocks up to 2 hours before the earliest key\n"
" creation time of all keys being imported by the importmulti call will be scanned.",
/*oneline_description=*/"", {"timestamp | \"now\"", "integer / string"}
"or the string \"now\" to substitute the current synced blockchain time. The timestamp of the oldest\n"
"key will determine how far back blockchain rescans need to begin for missing wallet transactions.\n"
"\"now\" can be specified to bypass scanning, for keys which are known to never have been used, and\n"
"0 can be specified to scan the entire blockchain. Blocks up to 2 hours before the earliest key\n"
"creation time of all keys being imported by the importmulti call will be scanned.",
RPCArgOptions{.type_str={"timestamp | \"now\"", "integer / string"}}
},
{"redeemscript", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "Allowed only if the scriptPubKey is a P2SH or P2SH-P2WSH address/scriptPubKey"},
{"witnessscript", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "Allowed only if the scriptPubKey is a P2SH-P2WSH or P2WSH address/scriptPubKey"},
@ -1296,12 +1296,12 @@ RPCHelpMan importmulti()
},
},
},
"\"requests\""},
RPCArgOptions{.oneline_description="\"requests\""}},
{"options", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED_NAMED_ARG, "",
{
{"rescan", RPCArg::Type::BOOL, RPCArg::Default{true}, "Scan the chain and mempool for wallet transactions after all imports."},
},
"\"options\""},
RPCArgOptions{.oneline_description="\"options\""}},
},
RPCResult{
RPCResult::Type::ARR, "", "Response is an array with the same size as the input that has the execution result",
@ -1609,18 +1609,18 @@ RPCHelpMan importdescriptors()
{"range", RPCArg::Type::RANGE, RPCArg::Optional::OMITTED, "If a ranged descriptor is used, this specifies the end or the range (in the form [begin,end]) to import"},
{"next_index", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "If a ranged descriptor is set to active, this specifies the next index to generate addresses from"},
{"timestamp", RPCArg::Type::NUM, RPCArg::Optional::NO, "Time from which to start rescanning the blockchain for this descriptor, in " + UNIX_EPOCH_TIME + "\n"
" Use the string \"now\" to substitute the current synced blockchain time.\n"
" \"now\" can be specified to bypass scanning, for outputs which are known to never have been used, and\n"
" 0 can be specified to scan the entire blockchain. Blocks up to 2 hours before the earliest timestamp\n"
"Use the string \"now\" to substitute the current synced blockchain time.\n"
"\"now\" can be specified to bypass scanning, for outputs which are known to never have been used, and\n"
"0 can be specified to scan the entire blockchain. Blocks up to 2 hours before the earliest timestamp\n"
"of all descriptors being imported will be scanned as well as the mempool.",
/*oneline_description=*/"", {"timestamp | \"now\"", "integer / string"}
RPCArgOptions{.type_str={"timestamp | \"now\"", "integer / string"}}
},
{"internal", RPCArg::Type::BOOL, RPCArg::Default{false}, "Whether matching outputs should be treated as not incoming payments (e.g. change)"},
{"label", RPCArg::Type::STR, RPCArg::Default{""}, "Label to assign to the address, only allowed with internal=false. Disabled for ranged descriptors"},
},
},
},
"\"requests\""},
RPCArgOptions{.oneline_description="\"requests\""}},
},
RPCResult{
RPCResult::Type::ARR, "", "Response is an array with the same size as the input that has the execution result",

View file

@ -516,7 +516,7 @@ RPCHelpMan listunspent()
{"maximumCount", RPCArg::Type::NUM, RPCArg::DefaultHint{"unlimited"}, "Maximum number of UTXOs"},
{"minimumSumAmount", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"unlimited"}, "Minimum sum value of all UTXOs in " + CURRENCY_UNIT + ""},
},
"query_options"},
RPCArgOptions{.oneline_description="query_options"}},
},
RPCResult{
RPCResult::Type::ARR, "", "",

View file

@ -317,7 +317,7 @@ RPCHelpMan sendmany()
"\nSend multiple times. Amounts are double-precision floating point numbers." +
HELP_REQUIRING_PASSPHRASE,
{
{"dummy", RPCArg::Type::STR, RPCArg::Optional::NO, "Must be set to \"\" for backwards compatibility.", "\"\""},
{"dummy", RPCArg::Type::STR, RPCArg::Optional::NO, "Must be set to \"\" for backwards compatibility.", RPCArgOptions{.oneline_description="\"\""}},
{"amounts", RPCArg::Type::OBJ_USER_KEYS, RPCArg::Optional::NO, "The addresses and amounts",
{
{"address", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "The bitcoin address is the key, the numeric amount (can be string) in " + CURRENCY_UNIT + " is the value"},
@ -774,7 +774,7 @@ RPCHelpMan fundrawtransaction()
},
},
FundTxDoc()),
"options"},
RPCArgOptions{.oneline_description="options"}},
{"iswitness", RPCArg::Type::BOOL, RPCArg::DefaultHint{"depends on heuristic tests"}, "Whether the transaction hex is a serialized witness transaction.\n"
"If iswitness is not present, heuristic tests will be used in decoding.\n"
"If true, only witness deserialization will be tried.\n"
@ -968,7 +968,7 @@ static RPCHelpMan bumpfee_helper(std::string method_name)
{"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, "The fee estimate mode, must be one of (case insensitive):\n"
"\"" + FeeModes("\"\n\"") + "\""},
},
"options"},
RPCArgOptions{.oneline_description="options"}},
},
RPCResult{
RPCResult::Type::OBJ, "", "", Cat(
@ -1173,7 +1173,7 @@ RPCHelpMan send()
},
},
FundTxDoc()),
"options"},
RPCArgOptions{.oneline_description="options"}},
},
RPCResult{
RPCResult::Type::OBJ, "", "",
@ -1281,7 +1281,7 @@ RPCHelpMan sendall()
},
FundTxDoc()
),
"options"
RPCArgOptions{.oneline_description="options"}
},
},
RPCResult{
@ -1611,7 +1611,7 @@ RPCHelpMan walletcreatefundedpsbt()
},
},
FundTxDoc()),
"options"},
RPCArgOptions{.oneline_description="options"}},
{"bip32derivs", RPCArg::Type::BOOL, RPCArg::Default{true}, "Include BIP 32 derivation paths for public keys if we know them"},
},
RPCResult{