mirror of https://github.com/bitcoin/bitcoin.git
cli: Allow arguments to be both strings and json
This commit is contained in:
parent
ad4a49090d
commit
44a493e150
|
@ -18,6 +18,7 @@ public:
|
|||
std::string methodName; //!< method whose params want conversion
|
||||
int paramIdx; //!< 0-based idx of param to convert
|
||||
std::string paramName; //!< parameter name
|
||||
bool also_string{false}; //!< The parameter is also a string
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
|
@ -188,10 +189,10 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
|||
{ "gettxout", 1, "n" },
|
||||
{ "gettxout", 2, "include_mempool" },
|
||||
{ "gettxoutproof", 0, "txids" },
|
||||
{ "gettxoutsetinfo", 1, "hash_or_height" },
|
||||
{ "gettxoutsetinfo", 1, "hash_or_height", /*also_string=*/true },
|
||||
{ "gettxoutsetinfo", 2, "use_index"},
|
||||
{ "dumptxoutset", 2, "options" },
|
||||
{ "dumptxoutset", 2, "rollback" },
|
||||
{ "dumptxoutset", 2, "rollback", /*also_string=*/true },
|
||||
{ "lockunspent", 0, "unlock" },
|
||||
{ "lockunspent", 1, "transactions" },
|
||||
{ "lockunspent", 2, "persistent" },
|
||||
|
@ -246,7 +247,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
|||
{ "listdescriptors", 0, "private" },
|
||||
{ "verifychain", 0, "checklevel" },
|
||||
{ "verifychain", 1, "nblocks" },
|
||||
{ "getblockstats", 0, "hash_or_height" },
|
||||
{ "getblockstats", 0, "hash_or_height", /*also_string=*/true },
|
||||
{ "getblockstats", 1, "stats" },
|
||||
{ "pruneblockchain", 0, "height" },
|
||||
{ "keypoolrefill", 0, "newsize" },
|
||||
|
@ -318,18 +319,21 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
|||
// clang-format on
|
||||
|
||||
/** Parse string to UniValue or throw runtime_error if string contains invalid JSON */
|
||||
static UniValue Parse(std::string_view raw)
|
||||
static UniValue Parse(std::string_view raw, bool also_string)
|
||||
{
|
||||
UniValue parsed;
|
||||
if (!parsed.read(raw)) throw std::runtime_error(tfm::format("Error parsing JSON: %s", raw));
|
||||
if (!parsed.read(raw)) {
|
||||
if (!also_string) throw std::runtime_error(tfm::format("Error parsing JSON: %s", raw));
|
||||
return raw;
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
|
||||
class CRPCConvertTable
|
||||
{
|
||||
private:
|
||||
std::set<std::pair<std::string, int>> members;
|
||||
std::set<std::pair<std::string, std::string>> membersByName;
|
||||
std::map<std::pair<std::string, int>, bool> members;
|
||||
std::map<std::pair<std::string, std::string>, bool> membersByName;
|
||||
|
||||
public:
|
||||
CRPCConvertTable();
|
||||
|
@ -337,21 +341,29 @@ public:
|
|||
/** Return arg_value as UniValue, and first parse it if it is a non-string parameter */
|
||||
UniValue ArgToUniValue(std::string_view arg_value, const std::string& method, int param_idx)
|
||||
{
|
||||
return members.count({method, param_idx}) > 0 ? Parse(arg_value) : arg_value;
|
||||
const auto& it = members.find({method, param_idx});
|
||||
if (it != members.end()) {
|
||||
return Parse(arg_value, it->second);
|
||||
}
|
||||
return arg_value;
|
||||
}
|
||||
|
||||
/** Return arg_value as UniValue, and first parse it if it is a non-string parameter */
|
||||
UniValue ArgToUniValue(std::string_view arg_value, const std::string& method, const std::string& param_name)
|
||||
{
|
||||
return membersByName.count({method, param_name}) > 0 ? Parse(arg_value) : arg_value;
|
||||
const auto& it = membersByName.find({method, param_name});
|
||||
if (it != membersByName.end()) {
|
||||
return Parse(arg_value, it->second);
|
||||
}
|
||||
return arg_value;
|
||||
}
|
||||
};
|
||||
|
||||
CRPCConvertTable::CRPCConvertTable()
|
||||
{
|
||||
for (const auto& cp : vRPCConvertParams) {
|
||||
members.emplace(cp.methodName, cp.paramIdx);
|
||||
membersByName.emplace(cp.methodName, cp.paramName);
|
||||
members.emplace(std::make_pair(cp.methodName, cp.paramIdx), cp.also_string);
|
||||
membersByName.emplace(std::make_pair(cp.methodName, cp.paramName), cp.also_string);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ def process_mapping(fname):
|
|||
if line.startswith('};'):
|
||||
in_rpcs = False
|
||||
elif '{' in line and '"' in line:
|
||||
m = re.search(r'{ *("[^"]*"), *([0-9]+) *, *("[^"]*") *},', line)
|
||||
m = re.search(r'{ *("[^"]*"), *([0-9]+) *, *("[^"]*") *(, \/\*also_string=\*\/true *)?},', line)
|
||||
assert m, 'No match to table expression: %s' % line
|
||||
name = parse_string(m.group(1))
|
||||
idx = int(m.group(2))
|
||||
|
|
Loading…
Reference in New Issue