cli: Allow arguments to be both strings and json

This commit is contained in:
Ava Chow committed 2025-09-23 12:57:34 -07:00
1 parent ad4a49090d
commit 44a493e150
2 files changed
+24 -12

No files matched your search

+23 -11
View File
@@ -18,6 +18,7 @@ public:
std::string methodName; //!< method whose params want conversion std::string methodName; //!< method whose params want conversion
int paramIdx; //!< 0-based idx of param to convert int paramIdx; //!< 0-based idx of param to convert
std::string paramName; //!< parameter name std::string paramName; //!< parameter name
bool also_string{false}; //!< The parameter is also a string
}; };
// clang-format off // clang-format off
@@ -188,10 +189,10 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "gettxout", 1, "n" }, { "gettxout", 1, "n" },
{ "gettxout", 2, "include_mempool" }, { "gettxout", 2, "include_mempool" },
{ "gettxoutproof", 0, "txids" }, { "gettxoutproof", 0, "txids" },
{ "gettxoutsetinfo", 1, "hash_or_height" }, { "gettxoutsetinfo", 1, "hash_or_height", /*also_string=*/true },
{ "gettxoutsetinfo", 2, "use_index"}, { "gettxoutsetinfo", 2, "use_index"},
{ "dumptxoutset", 2, "options" }, { "dumptxoutset", 2, "options" },
{ "dumptxoutset", 2, "rollback" }, { "dumptxoutset", 2, "rollback", /*also_string=*/true },
{ "lockunspent", 0, "unlock" }, { "lockunspent", 0, "unlock" },
{ "lockunspent", 1, "transactions" }, { "lockunspent", 1, "transactions" },
{ "lockunspent", 2, "persistent" }, { "lockunspent", 2, "persistent" },
@@ -246,7 +247,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "listdescriptors", 0, "private" }, { "listdescriptors", 0, "private" },
{ "verifychain", 0, "checklevel" }, { "verifychain", 0, "checklevel" },
{ "verifychain", 1, "nblocks" }, { "verifychain", 1, "nblocks" },
{ "getblockstats", 0, "hash_or_height" }, { "getblockstats", 0, "hash_or_height", /*also_string=*/true },
{ "getblockstats", 1, "stats" }, { "getblockstats", 1, "stats" },
{ "pruneblockchain", 0, "height" }, { "pruneblockchain", 0, "height" },
{ "keypoolrefill", 0, "newsize" }, { "keypoolrefill", 0, "newsize" },
@@ -318,18 +319,21 @@ static const CRPCConvertParam vRPCConvertParams[] =
// clang-format on // clang-format on
/** Parse string to UniValue or throw runtime_error if string contains invalid JSON */ /** 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; 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; return parsed;
} }
class CRPCConvertTable class CRPCConvertTable
{ {
private: private:
std::set<std::pair<std::string, int>> members; std::map<std::pair<std::string, int>, bool> members;
std::set<std::pair<std::string, std::string>> membersByName; std::map<std::pair<std::string, std::string>, bool> membersByName;
public: public:
CRPCConvertTable(); CRPCConvertTable();
@@ -337,21 +341,29 @@ public:
/** Return arg_value as UniValue, and first parse it if it is a non-string parameter */ /** 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) 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 */ /** 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) 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() CRPCConvertTable::CRPCConvertTable()
{ {
for (const auto& cp : vRPCConvertParams) { for (const auto& cp : vRPCConvertParams) {
members.emplace(cp.methodName, cp.paramIdx); members.emplace(std::make_pair(cp.methodName, cp.paramIdx), cp.also_string);
membersByName.emplace(cp.methodName, cp.paramName); membersByName.emplace(std::make_pair(cp.methodName, cp.paramName), cp.also_string);
} }
} }
+1 -1
View File
@@ -32,7 +32,7 @@ def process_mapping(fname):
if line.startswith('};'): if line.startswith('};'):
in_rpcs = False in_rpcs = False
elif '{' in line and '"' in line: 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 assert m, 'No match to table expression: %s' % line
name = parse_string(m.group(1)) name = parse_string(m.group(1))
idx = int(m.group(2)) idx = int(m.group(2))