Skip to content

Commit 5c184cb

Browse files
committed
Merge pull request #4415
e35b37b RPC client: Simplify command line string-to-JSON-value conversion code (Jeff Garzik)
2 parents 77888d6 + e35b37b commit 5c184cb

File tree

1 file changed

+104
-79
lines changed

1 file changed

+104
-79
lines changed

src/rpcclient.cpp

Lines changed: 104 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// Distributed under the MIT/X11 software license, see the accompanying
44
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
55

6+
#include <set>
67
#include "rpcclient.h"
78

89
#include "rpcprotocol.h"
@@ -15,94 +16,118 @@
1516
using namespace std;
1617
using namespace json_spirit;
1718

18-
template<typename T>
19-
void ConvertTo(Value& value, bool fAllowNull=false)
19+
class CRPCConvertParam
2020
{
21-
if (fAllowNull && value.type() == null_type)
22-
return;
23-
if (value.type() == str_type)
24-
{
25-
// reinterpret string as unquoted json value
26-
Value value2;
27-
string strJSON = value.get_str();
28-
if (!read_string(strJSON, value2))
29-
throw runtime_error(string("Error parsing JSON:")+strJSON);
30-
ConvertTo<T>(value2, fAllowNull);
31-
value = value2;
21+
public:
22+
std::string methodName; // method whose params want conversion
23+
int paramIdx; // 0-based idx of param to convert
24+
};
25+
26+
static const CRPCConvertParam vRPCConvertParams[] =
27+
{
28+
{ "stop", 0 },
29+
{ "getaddednodeinfo", 0 },
30+
{ "setgenerate", 0 },
31+
{ "setgenerate", 1 },
32+
{ "getnetworkhashps", 0 },
33+
{ "getnetworkhashps", 1 },
34+
{ "sendtoaddress", 1 },
35+
{ "settxfee", 0 },
36+
{ "getreceivedbyaddress", 1 },
37+
{ "getreceivedbyaccount", 1 },
38+
{ "listreceivedbyaddress", 0 },
39+
{ "listreceivedbyaddress", 1 },
40+
{ "listreceivedbyaccount", 0 },
41+
{ "listreceivedbyaccount", 1 },
42+
{ "getbalance", 1 },
43+
{ "getblockhash", 0 },
44+
{ "move", 2 },
45+
{ "move", 3 },
46+
{ "sendfrom", 2 },
47+
{ "sendfrom", 3 },
48+
{ "listtransactions", 1 },
49+
{ "listtransactions", 2 },
50+
{ "listaccounts", 0 },
51+
{ "walletpassphrase", 1 },
52+
{ "getblocktemplate", 0 },
53+
{ "listsinceblock", 1 },
54+
{ "sendmany", 1 },
55+
{ "sendmany", 2 },
56+
{ "addmultisigaddress", 0 },
57+
{ "addmultisigaddress", 1 },
58+
{ "createmultisig", 0 },
59+
{ "createmultisig", 1 },
60+
{ "listunspent", 0 },
61+
{ "listunspent", 1 },
62+
{ "listunspent", 2 },
63+
{ "getblock", 1 },
64+
{ "getrawtransaction", 1 },
65+
{ "createrawtransaction", 0 },
66+
{ "createrawtransaction", 1 },
67+
{ "signrawtransaction", 1 },
68+
{ "signrawtransaction", 2 },
69+
{ "sendrawtransaction", 1 },
70+
{ "gettxout", 1 },
71+
{ "gettxout", 2 },
72+
{ "lockunspent", 0 },
73+
{ "lockunspent", 1 },
74+
{ "importprivkey", 2 },
75+
{ "verifychain", 0 },
76+
{ "verifychain", 1 },
77+
{ "keypoolrefill", 0 },
78+
{ "getrawmempool", 0 },
79+
{ "estimatefee", 0 },
80+
{ "estimatepriority", 0 },
81+
};
82+
83+
class CRPCConvertTable
84+
{
85+
private:
86+
std::set<std::pair<std::string, int> > members;
87+
88+
public:
89+
CRPCConvertTable();
90+
91+
bool convert(const std::string& method, int idx) {
92+
return (members.count(std::make_pair(method, idx)) > 0);
3293
}
33-
else
34-
{
35-
value = value.get_value<T>();
94+
};
95+
96+
CRPCConvertTable::CRPCConvertTable()
97+
{
98+
const unsigned int n_elem =
99+
(sizeof(vRPCConvertParams) / sizeof(vRPCConvertParams[0]));
100+
101+
for (unsigned int i = 0; i < n_elem; i++) {
102+
members.insert(std::make_pair(vRPCConvertParams[i].methodName,
103+
vRPCConvertParams[i].paramIdx));
36104
}
37105
}
38106

107+
static CRPCConvertTable rpcCvtTable;
108+
39109
// Convert strings to command-specific RPC representation
40110
Array RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams)
41111
{
42112
Array params;
43-
BOOST_FOREACH(const std::string &param, strParams)
44-
params.push_back(param);
45-
46-
int n = params.size();
47-
48-
//
49-
// Special case non-string parameter types
50-
//
51-
if (strMethod == "stop" && n > 0) ConvertTo<bool>(params[0]);
52-
if (strMethod == "getaddednodeinfo" && n > 0) ConvertTo<bool>(params[0]);
53-
if (strMethod == "setgenerate" && n > 0) ConvertTo<bool>(params[0]);
54-
if (strMethod == "setgenerate" && n > 1) ConvertTo<int64_t>(params[1]);
55-
if (strMethod == "getnetworkhashps" && n > 0) ConvertTo<int64_t>(params[0]);
56-
if (strMethod == "getnetworkhashps" && n > 1) ConvertTo<int64_t>(params[1]);
57-
if (strMethod == "sendtoaddress" && n > 1) ConvertTo<double>(params[1]);
58-
if (strMethod == "settxfee" && n > 0) ConvertTo<double>(params[0]);
59-
if (strMethod == "getreceivedbyaddress" && n > 1) ConvertTo<int64_t>(params[1]);
60-
if (strMethod == "getreceivedbyaccount" && n > 1) ConvertTo<int64_t>(params[1]);
61-
if (strMethod == "listreceivedbyaddress" && n > 0) ConvertTo<int64_t>(params[0]);
62-
if (strMethod == "listreceivedbyaddress" && n > 1) ConvertTo<bool>(params[1]);
63-
if (strMethod == "listreceivedbyaccount" && n > 0) ConvertTo<int64_t>(params[0]);
64-
if (strMethod == "listreceivedbyaccount" && n > 1) ConvertTo<bool>(params[1]);
65-
if (strMethod == "getbalance" && n > 1) ConvertTo<int64_t>(params[1]);
66-
if (strMethod == "getblockhash" && n > 0) ConvertTo<int64_t>(params[0]);
67-
if (strMethod == "move" && n > 2) ConvertTo<double>(params[2]);
68-
if (strMethod == "move" && n > 3) ConvertTo<int64_t>(params[3]);
69-
if (strMethod == "sendfrom" && n > 2) ConvertTo<double>(params[2]);
70-
if (strMethod == "sendfrom" && n > 3) ConvertTo<int64_t>(params[3]);
71-
if (strMethod == "listtransactions" && n > 1) ConvertTo<int64_t>(params[1]);
72-
if (strMethod == "listtransactions" && n > 2) ConvertTo<int64_t>(params[2]);
73-
if (strMethod == "listaccounts" && n > 0) ConvertTo<int64_t>(params[0]);
74-
if (strMethod == "walletpassphrase" && n > 1) ConvertTo<int64_t>(params[1]);
75-
if (strMethod == "prioritisetransaction" && n > 1) ConvertTo<double>(params[1]);
76-
if (strMethod == "prioritisetransaction" && n > 2) ConvertTo<int64_t>(params[2]);
77-
if (strMethod == "getblocktemplate" && n > 0) ConvertTo<Object>(params[0]);
78-
if (strMethod == "listsinceblock" && n > 1) ConvertTo<int64_t>(params[1]);
79-
if (strMethod == "sendmany" && n > 1) ConvertTo<Object>(params[1]);
80-
if (strMethod == "sendmany" && n > 2) ConvertTo<int64_t>(params[2]);
81-
if (strMethod == "addmultisigaddress" && n > 0) ConvertTo<int64_t>(params[0]);
82-
if (strMethod == "addmultisigaddress" && n > 1) ConvertTo<Array>(params[1]);
83-
if (strMethod == "createmultisig" && n > 0) ConvertTo<int64_t>(params[0]);
84-
if (strMethod == "createmultisig" && n > 1) ConvertTo<Array>(params[1]);
85-
if (strMethod == "listunspent" && n > 0) ConvertTo<int64_t>(params[0]);
86-
if (strMethod == "listunspent" && n > 1) ConvertTo<int64_t>(params[1]);
87-
if (strMethod == "listunspent" && n > 2) ConvertTo<Array>(params[2]);
88-
if (strMethod == "getblock" && n > 1) ConvertTo<bool>(params[1]);
89-
if (strMethod == "getrawtransaction" && n > 1) ConvertTo<int64_t>(params[1]);
90-
if (strMethod == "createrawtransaction" && n > 0) ConvertTo<Array>(params[0]);
91-
if (strMethod == "createrawtransaction" && n > 1) ConvertTo<Object>(params[1]);
92-
if (strMethod == "signrawtransaction" && n > 1) ConvertTo<Array>(params[1], true);
93-
if (strMethod == "signrawtransaction" && n > 2) ConvertTo<Array>(params[2], true);
94-
if (strMethod == "sendrawtransaction" && n > 1) ConvertTo<bool>(params[1], true);
95-
if (strMethod == "gettxout" && n > 1) ConvertTo<int64_t>(params[1]);
96-
if (strMethod == "gettxout" && n > 2) ConvertTo<bool>(params[2]);
97-
if (strMethod == "lockunspent" && n > 0) ConvertTo<bool>(params[0]);
98-
if (strMethod == "lockunspent" && n > 1) ConvertTo<Array>(params[1]);
99-
if (strMethod == "importprivkey" && n > 2) ConvertTo<bool>(params[2]);
100-
if (strMethod == "verifychain" && n > 0) ConvertTo<int64_t>(params[0]);
101-
if (strMethod == "verifychain" && n > 1) ConvertTo<int64_t>(params[1]);
102-
if (strMethod == "keypoolrefill" && n > 0) ConvertTo<int64_t>(params[0]);
103-
if (strMethod == "getrawmempool" && n > 0) ConvertTo<bool>(params[0]);
104-
if (strMethod == "estimatefee" && n > 0) ConvertTo<boost::int64_t>(params[0]);
105-
if (strMethod == "estimatepriority" && n > 0) ConvertTo<boost::int64_t>(params[0]);
113+
114+
for (unsigned int idx = 0; idx < strParams.size(); idx++) {
115+
const std::string& strVal = strParams[idx];
116+
117+
// insert string value directly
118+
if (!rpcCvtTable.convert(strMethod, idx)) {
119+
params.push_back(strVal);
120+
}
121+
122+
// parse string as JSON, insert bool/number/object/etc. value
123+
else {
124+
Value jVal;
125+
if (!read_string(strVal, jVal))
126+
throw runtime_error(string("Error parsing JSON:")+strVal);
127+
params.push_back(jVal);
128+
}
129+
130+
}
106131

107132
return params;
108133
}

0 commit comments

Comments
 (0)