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-ACKfa2c72dda0
Tree-SHA512: 2a0619548187cc7437fee2466ac4780746490622f202659f53641be01bc2a1fea4416d1a77f3e963bf7c4cce62899b61fab0b9683440cf82f68be44f63826658
This commit is contained in:
commit
33eef562a3
8 changed files with 47 additions and 49 deletions
|
@ -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, "", "", {
|
||||
|
|
|
@ -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, "", ""},
|
||||
|
|
|
@ -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{""},
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
/**
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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, "", "",
|
||||
|
|
|
@ -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{
|
||||
|
|
Loading…
Add table
Reference in a new issue