Skip to content

Commit 44a493e

Browse files
committed
cli: Allow arguments to be both strings and json
1 parent ad4a490 commit 44a493e

File tree

2 files changed

+24
-12
lines changed

2 files changed

+24
-12
lines changed

src/rpc/client.cpp

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class CRPCConvertParam
1818
std::string methodName; //!< method whose params want conversion
1919
int paramIdx; //!< 0-based idx of param to convert
2020
std::string paramName; //!< parameter name
21+
bool also_string{false}; //!< The parameter is also a string
2122
};
2223

2324
// clang-format off
@@ -188,10 +189,10 @@ static const CRPCConvertParam vRPCConvertParams[] =
188189
{ "gettxout", 1, "n" },
189190
{ "gettxout", 2, "include_mempool" },
190191
{ "gettxoutproof", 0, "txids" },
191-
{ "gettxoutsetinfo", 1, "hash_or_height" },
192+
{ "gettxoutsetinfo", 1, "hash_or_height", /*also_string=*/true },
192193
{ "gettxoutsetinfo", 2, "use_index"},
193194
{ "dumptxoutset", 2, "options" },
194-
{ "dumptxoutset", 2, "rollback" },
195+
{ "dumptxoutset", 2, "rollback", /*also_string=*/true },
195196
{ "lockunspent", 0, "unlock" },
196197
{ "lockunspent", 1, "transactions" },
197198
{ "lockunspent", 2, "persistent" },
@@ -246,7 +247,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
246247
{ "listdescriptors", 0, "private" },
247248
{ "verifychain", 0, "checklevel" },
248249
{ "verifychain", 1, "nblocks" },
249-
{ "getblockstats", 0, "hash_or_height" },
250+
{ "getblockstats", 0, "hash_or_height", /*also_string=*/true },
250251
{ "getblockstats", 1, "stats" },
251252
{ "pruneblockchain", 0, "height" },
252253
{ "keypoolrefill", 0, "newsize" },
@@ -318,40 +319,51 @@ static const CRPCConvertParam vRPCConvertParams[] =
318319
// clang-format on
319320

320321
/** Parse string to UniValue or throw runtime_error if string contains invalid JSON */
321-
static UniValue Parse(std::string_view raw)
322+
static UniValue Parse(std::string_view raw, bool also_string)
322323
{
323324
UniValue parsed;
324-
if (!parsed.read(raw)) throw std::runtime_error(tfm::format("Error parsing JSON: %s", raw));
325+
if (!parsed.read(raw)) {
326+
if (!also_string) throw std::runtime_error(tfm::format("Error parsing JSON: %s", raw));
327+
return raw;
328+
}
325329
return parsed;
326330
}
327331

328332
class CRPCConvertTable
329333
{
330334
private:
331-
std::set<std::pair<std::string, int>> members;
332-
std::set<std::pair<std::string, std::string>> membersByName;
335+
std::map<std::pair<std::string, int>, bool> members;
336+
std::map<std::pair<std::string, std::string>, bool> membersByName;
333337

334338
public:
335339
CRPCConvertTable();
336340

337341
/** Return arg_value as UniValue, and first parse it if it is a non-string parameter */
338342
UniValue ArgToUniValue(std::string_view arg_value, const std::string& method, int param_idx)
339343
{
340-
return members.count({method, param_idx}) > 0 ? Parse(arg_value) : arg_value;
344+
const auto& it = members.find({method, param_idx});
345+
if (it != members.end()) {
346+
return Parse(arg_value, it->second);
347+
}
348+
return arg_value;
341349
}
342350

343351
/** Return arg_value as UniValue, and first parse it if it is a non-string parameter */
344352
UniValue ArgToUniValue(std::string_view arg_value, const std::string& method, const std::string& param_name)
345353
{
346-
return membersByName.count({method, param_name}) > 0 ? Parse(arg_value) : arg_value;
354+
const auto& it = membersByName.find({method, param_name});
355+
if (it != membersByName.end()) {
356+
return Parse(arg_value, it->second);
357+
}
358+
return arg_value;
347359
}
348360
};
349361

350362
CRPCConvertTable::CRPCConvertTable()
351363
{
352364
for (const auto& cp : vRPCConvertParams) {
353-
members.emplace(cp.methodName, cp.paramIdx);
354-
membersByName.emplace(cp.methodName, cp.paramName);
365+
members.emplace(std::make_pair(cp.methodName, cp.paramIdx), cp.also_string);
366+
membersByName.emplace(std::make_pair(cp.methodName, cp.paramName), cp.also_string);
355367
}
356368
}
357369

test/functional/rpc_help.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def process_mapping(fname):
3232
if line.startswith('};'):
3333
in_rpcs = False
3434
elif '{' in line and '"' in line:
35-
m = re.search(r'{ *("[^"]*"), *([0-9]+) *, *("[^"]*") *},', line)
35+
m = re.search(r'{ *("[^"]*"), *([0-9]+) *, *("[^"]*") *(, \/\*also_string=\*\/true *)?},', line)
3636
assert m, 'No match to table expression: %s' % line
3737
name = parse_string(m.group(1))
3838
idx = int(m.group(2))

0 commit comments

Comments
 (0)