Branch data Line data Source code
1 : : // Copyright (c) 2010 Satoshi Nakamoto
2 : : // Copyright (c) 2009-2022 The Bitcoin Core developers
3 : : // Distributed under the MIT software license, see the accompanying
4 : : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 : :
6 : : #include <common/args.h>
7 : : #include <rpc/client.h>
8 : : #include <tinyformat.h>
9 : :
10 : : #include <set>
11 : : #include <stdint.h>
12 : : #include <string>
13 : : #include <string_view>
14 : :
15 : : class CRPCConvertParam
16 : : {
17 : : public:
18 : : std::string methodName; //!< method whose params want conversion
19 : : int paramIdx; //!< 0-based idx of param to convert
20 : : std::string paramName; //!< parameter name
21 : : };
22 : :
23 : : // clang-format off
24 : : /**
25 : : * Specify a (method, idx, name) here if the argument is a non-string RPC
26 : : * argument and needs to be converted from JSON.
27 : : *
28 : : * @note Parameter indexes start from 0.
29 : : */
30 : 0 : static const CRPCConvertParam vRPCConvertParams[] =
31 [ # # # # : 546 : {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
32 [ + - + - ]: 2 : { "setmocktime", 0, "timestamp" },
33 [ + - + - ]: 2 : { "mockscheduler", 0, "delta_time" },
34 [ + - + - ]: 2 : { "utxoupdatepsbt", 1, "descriptors" },
35 [ + - + - ]: 2 : { "generatetoaddress", 0, "nblocks" },
36 [ + - + - ]: 2 : { "generatetoaddress", 2, "maxtries" },
37 [ + - + - ]: 2 : { "generatetodescriptor", 0, "num_blocks" },
38 [ + - + - ]: 2 : { "generatetodescriptor", 2, "maxtries" },
39 [ + - + - ]: 2 : { "generateblock", 1, "transactions" },
40 [ + - + - ]: 2 : { "generateblock", 2, "submit" },
41 [ + - + - ]: 2 : { "getnetworkhashps", 0, "nblocks" },
42 [ + - + - ]: 2 : { "getnetworkhashps", 1, "height" },
43 [ + - + - ]: 2 : { "sendtoaddress", 1, "amount" },
44 [ + - + - ]: 2 : { "sendtoaddress", 4, "subtractfeefromamount" },
45 [ + - + - ]: 2 : { "sendtoaddress", 5 , "replaceable" },
46 [ + - + - ]: 2 : { "sendtoaddress", 6 , "conf_target" },
47 [ + - + - ]: 2 : { "sendtoaddress", 8, "avoid_reuse" },
48 [ + - + - ]: 2 : { "sendtoaddress", 9, "fee_rate"},
49 [ + - + - ]: 2 : { "sendtoaddress", 10, "verbose"},
50 [ + - + - ]: 2 : { "settxfee", 0, "amount" },
51 [ + - + - ]: 2 : { "sethdseed", 0, "newkeypool" },
52 [ + - + - ]: 2 : { "getreceivedbyaddress", 1, "minconf" },
53 [ + - + - ]: 2 : { "getreceivedbyaddress", 2, "include_immature_coinbase" },
54 [ + - + - ]: 2 : { "getreceivedbylabel", 1, "minconf" },
55 [ + - + - ]: 2 : { "getreceivedbylabel", 2, "include_immature_coinbase" },
56 [ + - + - ]: 2 : { "listreceivedbyaddress", 0, "minconf" },
57 [ + - + - ]: 2 : { "listreceivedbyaddress", 1, "include_empty" },
58 [ + - + - ]: 2 : { "listreceivedbyaddress", 2, "include_watchonly" },
59 [ + - + - ]: 2 : { "listreceivedbyaddress", 4, "include_immature_coinbase" },
60 [ + - + - ]: 2 : { "listreceivedbylabel", 0, "minconf" },
61 [ + - + - ]: 2 : { "listreceivedbylabel", 1, "include_empty" },
62 [ + - + - ]: 2 : { "listreceivedbylabel", 2, "include_watchonly" },
63 [ + - + - ]: 2 : { "listreceivedbylabel", 3, "include_immature_coinbase" },
64 [ + - + - ]: 2 : { "getbalance", 1, "minconf" },
65 [ + - + - ]: 2 : { "getbalance", 2, "include_watchonly" },
66 [ + - + - ]: 2 : { "getbalance", 3, "avoid_reuse" },
67 [ + - + - ]: 2 : { "getblockfrompeer", 1, "peer_id" },
68 [ + - + - ]: 2 : { "getblockhash", 0, "height" },
69 [ + - + - ]: 2 : { "waitforblockheight", 0, "height" },
70 [ + - + - ]: 2 : { "waitforblockheight", 1, "timeout" },
71 [ + - + - ]: 2 : { "waitforblock", 1, "timeout" },
72 [ + - + - ]: 2 : { "waitfornewblock", 0, "timeout" },
73 [ + - + - ]: 2 : { "listtransactions", 1, "count" },
74 [ + - + - ]: 4 : { "listtransactions", 2, "skip" },
75 [ + - + - ]: 2 : { "listtransactions", 3, "include_watchonly" },
76 [ + - + - ]: 2 : { "walletpassphrase", 1, "timeout" },
77 [ + - + - ]: 2 : { "getblocktemplate", 0, "template_request" },
78 [ + - + - ]: 2 : { "listsinceblock", 1, "target_confirmations" },
79 [ + - + - ]: 2 : { "listsinceblock", 2, "include_watchonly" },
80 [ + - + - ]: 2 : { "listsinceblock", 3, "include_removed" },
81 [ + - + - ]: 2 : { "listsinceblock", 4, "include_change" },
82 [ + - + - ]: 2 : { "sendmany", 1, "amounts" },
83 [ + - + - ]: 2 : { "sendmany", 2, "minconf" },
84 [ + - + - ]: 2 : { "sendmany", 4, "subtractfeefrom" },
85 [ + - + - ]: 2 : { "sendmany", 5 , "replaceable" },
86 [ + - + - ]: 2 : { "sendmany", 6 , "conf_target" },
87 [ + - + - ]: 2 : { "sendmany", 8, "fee_rate"},
88 [ + - + - ]: 2 : { "sendmany", 9, "verbose" },
89 [ + - + - ]: 2 : { "deriveaddresses", 1, "range" },
90 [ + - + - ]: 2 : { "scanblocks", 1, "scanobjects" },
91 [ + - + - ]: 2 : { "scanblocks", 2, "start_height" },
92 [ + - + - ]: 2 : { "scanblocks", 3, "stop_height" },
93 [ + - + - ]: 2 : { "scanblocks", 5, "options" },
94 [ + - + - ]: 2 : { "scantxoutset", 1, "scanobjects" },
95 [ + - + - ]: 2 : { "addmultisigaddress", 0, "nrequired" },
96 [ + - + - ]: 2 : { "addmultisigaddress", 1, "keys" },
97 [ + - + - ]: 2 : { "createmultisig", 0, "nrequired" },
98 [ + - + - ]: 2 : { "createmultisig", 1, "keys" },
99 [ + - + - ]: 2 : { "listunspent", 0, "minconf" },
100 [ + - + - ]: 2 : { "listunspent", 1, "maxconf" },
101 [ + - + - ]: 2 : { "listunspent", 2, "addresses" },
102 [ + - + - ]: 2 : { "listunspent", 3, "include_unsafe" },
103 [ + - + - ]: 2 : { "listunspent", 4, "query_options" },
104 [ + - + - ]: 2 : { "listunspent", 4, "minimumAmount" },
105 [ + - + - ]: 2 : { "listunspent", 4, "maximumAmount" },
106 [ + - + - ]: 2 : { "listunspent", 4, "maximumCount" },
107 [ + - + - ]: 2 : { "listunspent", 4, "minimumSumAmount" },
108 [ + - + - ]: 2 : { "listunspent", 4, "include_immature_coinbase" },
109 [ + - + - ]: 2 : { "getblock", 1, "verbosity" },
110 [ + - + - ]: 2 : { "getblock", 1, "verbose" },
111 [ + - + - ]: 2 : { "getblockheader", 1, "verbose" },
112 [ + - + - ]: 2 : { "getchaintxstats", 0, "nblocks" },
113 [ + - + - ]: 2 : { "gettransaction", 1, "include_watchonly" },
114 [ + - + - ]: 2 : { "gettransaction", 2, "verbose" },
115 [ + - + - ]: 2 : { "getrawtransaction", 1, "verbosity" },
116 [ + - + - ]: 2 : { "getrawtransaction", 1, "verbose" },
117 [ + - + - ]: 2 : { "createrawtransaction", 0, "inputs" },
118 [ + - + - ]: 2 : { "createrawtransaction", 1, "outputs" },
119 [ + - + - ]: 2 : { "createrawtransaction", 2, "locktime" },
120 [ + - + - ]: 2 : { "createrawtransaction", 3, "replaceable" },
121 [ + - + - ]: 2 : { "decoderawtransaction", 1, "iswitness" },
122 [ + - + - ]: 2 : { "signrawtransactionwithkey", 1, "privkeys" },
123 [ + - + - ]: 2 : { "signrawtransactionwithkey", 2, "prevtxs" },
124 [ + - + - ]: 2 : { "signrawtransactionwithwallet", 1, "prevtxs" },
125 [ + - + - ]: 2 : { "sendrawtransaction", 1, "maxfeerate" },
126 [ + - + - ]: 2 : { "sendrawtransaction", 2, "maxburnamount" },
127 [ + - + - ]: 2 : { "testmempoolaccept", 0, "rawtxs" },
128 [ + - + - ]: 2 : { "testmempoolaccept", 1, "maxfeerate" },
129 [ + - + - ]: 2 : { "submitpackage", 0, "package" },
130 [ + - + - ]: 2 : { "combinerawtransaction", 0, "txs" },
131 [ + - + - ]: 2 : { "fundrawtransaction", 1, "options" },
132 [ + - + - ]: 2 : { "fundrawtransaction", 1, "add_inputs"},
133 [ + - + - ]: 2 : { "fundrawtransaction", 1, "include_unsafe"},
134 [ + - + - ]: 2 : { "fundrawtransaction", 1, "minconf"},
135 [ + - + - ]: 2 : { "fundrawtransaction", 1, "maxconf"},
136 [ + - + - ]: 2 : { "fundrawtransaction", 1, "changePosition"},
137 [ + - + - ]: 2 : { "fundrawtransaction", 1, "includeWatching"},
138 [ + - + - ]: 2 : { "fundrawtransaction", 1, "lockUnspents"},
139 [ + - + - ]: 2 : { "fundrawtransaction", 1, "fee_rate"},
140 [ + - + - ]: 2 : { "fundrawtransaction", 1, "feeRate"},
141 [ + - + - ]: 2 : { "fundrawtransaction", 1, "subtractFeeFromOutputs"},
142 [ + - + - ]: 2 : { "fundrawtransaction", 1, "input_weights"},
143 [ + - + - ]: 2 : { "fundrawtransaction", 1, "conf_target"},
144 [ + - + - ]: 2 : { "fundrawtransaction", 1, "replaceable"},
145 [ + - + - ]: 2 : { "fundrawtransaction", 1, "solving_data"},
146 [ + - + - ]: 2 : { "fundrawtransaction", 2, "iswitness" },
147 [ + - + - ]: 2 : { "walletcreatefundedpsbt", 0, "inputs" },
148 [ + - + - ]: 2 : { "walletcreatefundedpsbt", 1, "outputs" },
149 [ + - + - ]: 2 : { "walletcreatefundedpsbt", 2, "locktime" },
150 [ + - + - ]: 2 : { "walletcreatefundedpsbt", 3, "options" },
151 [ + - + - ]: 2 : { "walletcreatefundedpsbt", 3, "add_inputs"},
152 [ + - + - ]: 2 : { "walletcreatefundedpsbt", 3, "include_unsafe"},
153 [ + - + - ]: 2 : { "walletcreatefundedpsbt", 3, "minconf"},
154 [ + - + - ]: 2 : { "walletcreatefundedpsbt", 3, "maxconf"},
155 [ + - + - ]: 2 : { "walletcreatefundedpsbt", 3, "changePosition"},
156 [ + - + - ]: 2 : { "walletcreatefundedpsbt", 3, "includeWatching"},
157 [ + - + - ]: 2 : { "walletcreatefundedpsbt", 3, "lockUnspents"},
158 [ + - + - ]: 2 : { "walletcreatefundedpsbt", 3, "fee_rate"},
159 [ + - + - ]: 2 : { "walletcreatefundedpsbt", 3, "feeRate"},
160 [ + - + - ]: 2 : { "walletcreatefundedpsbt", 3, "subtractFeeFromOutputs"},
161 [ + - + - ]: 2 : { "walletcreatefundedpsbt", 3, "conf_target"},
162 [ + - + - ]: 2 : { "walletcreatefundedpsbt", 3, "replaceable"},
163 [ + - + - ]: 2 : { "walletcreatefundedpsbt", 3, "solving_data"},
164 [ + - + - ]: 2 : { "walletcreatefundedpsbt", 4, "bip32derivs" },
165 [ + - + - ]: 2 : { "walletprocesspsbt", 1, "sign" },
166 [ + - + - ]: 2 : { "walletprocesspsbt", 3, "bip32derivs" },
167 [ + - + - ]: 2 : { "walletprocesspsbt", 4, "finalize" },
168 [ + - + - ]: 2 : { "descriptorprocesspsbt", 1, "descriptors"},
169 [ + - + - ]: 2 : { "descriptorprocesspsbt", 3, "bip32derivs" },
170 [ + - + - ]: 2 : { "descriptorprocesspsbt", 4, "finalize" },
171 [ + - + - ]: 2 : { "createpsbt", 0, "inputs" },
172 [ + - + - ]: 2 : { "createpsbt", 1, "outputs" },
173 [ + - + - ]: 2 : { "createpsbt", 2, "locktime" },
174 [ + - + - ]: 2 : { "createpsbt", 3, "replaceable" },
175 [ + - + - ]: 2 : { "combinepsbt", 0, "txs"},
176 [ + - + - ]: 2 : { "joinpsbts", 0, "txs"},
177 [ + - + - ]: 2 : { "finalizepsbt", 1, "extract"},
178 [ + - + - ]: 2 : { "converttopsbt", 1, "permitsigdata"},
179 [ + - + - ]: 2 : { "converttopsbt", 2, "iswitness"},
180 [ + - + - ]: 2 : { "gettxout", 1, "n" },
181 [ + - + - ]: 2 : { "gettxout", 2, "include_mempool" },
182 [ + - + - ]: 2 : { "gettxoutproof", 0, "txids" },
183 [ + - + - ]: 2 : { "gettxoutsetinfo", 1, "hash_or_height" },
184 [ + - + - ]: 2 : { "gettxoutsetinfo", 2, "use_index"},
185 [ + - + - ]: 2 : { "lockunspent", 0, "unlock" },
186 [ + - + - ]: 2 : { "lockunspent", 1, "transactions" },
187 [ + - + - ]: 2 : { "lockunspent", 2, "persistent" },
188 [ + - + - ]: 2 : { "send", 0, "outputs" },
189 [ + - + - ]: 2 : { "send", 1, "conf_target" },
190 [ + - + - ]: 2 : { "send", 3, "fee_rate"},
191 [ + - + - ]: 2 : { "send", 4, "options" },
192 [ + - + - ]: 2 : { "send", 4, "add_inputs"},
193 [ + - + - ]: 2 : { "send", 4, "include_unsafe"},
194 [ + - + - ]: 2 : { "send", 4, "minconf"},
195 [ + - + - ]: 2 : { "send", 4, "maxconf"},
196 [ + - + - ]: 2 : { "send", 4, "add_to_wallet"},
197 [ + - + - ]: 2 : { "send", 4, "change_position"},
198 [ + - + - ]: 2 : { "send", 4, "fee_rate"},
199 [ + - + - ]: 2 : { "send", 4, "include_watching"},
200 [ + - + - ]: 2 : { "send", 4, "inputs"},
201 [ + - + - ]: 2 : { "send", 4, "locktime"},
202 [ + - + - ]: 2 : { "send", 4, "lock_unspents"},
203 [ + - + - ]: 2 : { "send", 4, "psbt"},
204 [ + - + - ]: 2 : { "send", 4, "subtract_fee_from_outputs"},
205 [ + - + - ]: 2 : { "send", 4, "conf_target"},
206 [ + - + - ]: 2 : { "send", 4, "replaceable"},
207 [ + - + - ]: 2 : { "send", 4, "solving_data"},
208 [ + - + - ]: 2 : { "sendall", 0, "recipients" },
209 [ + - + - ]: 2 : { "sendall", 1, "conf_target" },
210 [ + - + - ]: 2 : { "sendall", 3, "fee_rate"},
211 [ + - + - ]: 2 : { "sendall", 4, "options" },
212 [ + - + - ]: 2 : { "sendall", 4, "add_to_wallet"},
213 [ + - + - ]: 2 : { "sendall", 4, "fee_rate"},
214 [ + - + - ]: 2 : { "sendall", 4, "include_watching"},
215 [ + - + - ]: 2 : { "sendall", 4, "inputs"},
216 [ + - + - ]: 2 : { "sendall", 4, "locktime"},
217 [ + - + - ]: 2 : { "sendall", 4, "lock_unspents"},
218 [ + - + - ]: 2 : { "sendall", 4, "psbt"},
219 [ + - + - ]: 2 : { "sendall", 4, "send_max"},
220 [ + - + - ]: 2 : { "sendall", 4, "minconf"},
221 [ + - + - ]: 2 : { "sendall", 4, "maxconf"},
222 [ + - + - ]: 2 : { "sendall", 4, "conf_target"},
223 [ + - + - ]: 2 : { "sendall", 4, "replaceable"},
224 [ + - + - ]: 2 : { "sendall", 4, "solving_data"},
225 [ + - + - ]: 2 : { "simulaterawtransaction", 0, "rawtxs" },
226 [ + - + - ]: 2 : { "simulaterawtransaction", 1, "options" },
227 [ + - + - ]: 2 : { "simulaterawtransaction", 1, "include_watchonly"},
228 [ + - + - ]: 2 : { "importprivkey", 2, "rescan" },
229 [ + - + - ]: 2 : { "importaddress", 2, "rescan" },
230 [ + - + - ]: 2 : { "importaddress", 3, "p2sh" },
231 [ + - + - ]: 2 : { "importpubkey", 2, "rescan" },
232 [ + - + - ]: 2 : { "importmempool", 1, "options" },
233 [ + - + - ]: 2 : { "importmempool", 1, "apply_fee_delta_priority" },
234 [ + - + - ]: 2 : { "importmempool", 1, "use_current_time" },
235 [ + - + - ]: 2 : { "importmempool", 1, "apply_unbroadcast_set" },
236 [ + - + - ]: 2 : { "importmulti", 0, "requests" },
237 [ + - + - ]: 2 : { "importmulti", 1, "options" },
238 [ + - + - ]: 2 : { "importmulti", 1, "rescan" },
239 [ + - + - ]: 2 : { "importdescriptors", 0, "requests" },
240 [ + - + - ]: 2 : { "listdescriptors", 0, "private" },
241 [ + - + - ]: 2 : { "verifychain", 0, "checklevel" },
242 [ + - + - ]: 2 : { "verifychain", 1, "nblocks" },
243 [ + - + - ]: 2 : { "getblockstats", 0, "hash_or_height" },
244 [ + - + - ]: 2 : { "getblockstats", 1, "stats" },
245 [ + - + - ]: 2 : { "pruneblockchain", 0, "height" },
246 [ + - + - ]: 2 : { "keypoolrefill", 0, "newsize" },
247 [ + - + - ]: 2 : { "getrawmempool", 0, "verbose" },
248 [ + - + - ]: 2 : { "getrawmempool", 1, "mempool_sequence" },
249 [ + - + - ]: 2 : { "estimatesmartfee", 0, "conf_target" },
250 [ + - + - ]: 2 : { "estimaterawfee", 0, "conf_target" },
251 [ + - + - ]: 2 : { "estimaterawfee", 1, "threshold" },
252 [ + - + - ]: 2 : { "prioritisetransaction", 1, "dummy" },
253 [ + - + - ]: 2 : { "prioritisetransaction", 2, "fee_delta" },
254 [ + - + - ]: 2 : { "setban", 2, "bantime" },
255 [ + - + - ]: 2 : { "setban", 3, "absolute" },
256 [ + - + - ]: 2 : { "setnetworkactive", 0, "state" },
257 [ + - + - ]: 2 : { "setwalletflag", 1, "value" },
258 [ + - + - ]: 2 : { "getmempoolancestors", 1, "verbose" },
259 [ + - + - ]: 2 : { "getmempooldescendants", 1, "verbose" },
260 [ + - + - ]: 2 : { "gettxspendingprevout", 0, "outputs" },
261 [ + - + - ]: 2 : { "bumpfee", 1, "options" },
262 [ + - + - ]: 2 : { "bumpfee", 1, "conf_target"},
263 [ + - + - ]: 2 : { "bumpfee", 1, "fee_rate"},
264 [ + - + - ]: 2 : { "bumpfee", 1, "replaceable"},
265 [ + - + - ]: 2 : { "bumpfee", 1, "outputs"},
266 [ + - + - ]: 2 : { "bumpfee", 1, "original_change_index"},
267 [ + - + - ]: 2 : { "psbtbumpfee", 1, "options" },
268 [ + - + - ]: 2 : { "psbtbumpfee", 1, "conf_target"},
269 [ + - + - ]: 2 : { "psbtbumpfee", 1, "fee_rate"},
270 [ + - + - ]: 2 : { "psbtbumpfee", 1, "replaceable"},
271 [ + - + - ]: 2 : { "psbtbumpfee", 1, "outputs"},
272 [ + - + - ]: 2 : { "psbtbumpfee", 1, "original_change_index"},
273 [ + - + - ]: 2 : { "logging", 0, "include" },
274 [ + - + - ]: 2 : { "logging", 1, "exclude" },
275 [ + - + - ]: 2 : { "disconnectnode", 1, "nodeid" },
276 [ + - + - ]: 2 : { "upgradewallet", 0, "version" },
277 : : // Echo with conversion (For testing only)
278 [ + - + - ]: 2 : { "echojson", 0, "arg0" },
279 [ + - + - ]: 2 : { "echojson", 1, "arg1" },
280 [ + - + - ]: 2 : { "echojson", 2, "arg2" },
281 [ + - + - ]: 2 : { "echojson", 3, "arg3" },
282 [ + - + - ]: 2 : { "echojson", 4, "arg4" },
283 [ + - + - ]: 2 : { "echojson", 5, "arg5" },
284 [ + - + - ]: 2 : { "echojson", 6, "arg6" },
285 [ + - + - ]: 2 : { "echojson", 7, "arg7" },
286 [ + - + - ]: 2 : { "echojson", 8, "arg8" },
287 [ + - + - ]: 2 : { "echojson", 9, "arg9" },
288 [ + - + - ]: 2 : { "rescanblockchain", 0, "start_height"},
289 [ + - + - ]: 2 : { "rescanblockchain", 1, "stop_height"},
290 [ + - + - ]: 2 : { "createwallet", 1, "disable_private_keys"},
291 [ + - + - ]: 2 : { "createwallet", 2, "blank"},
292 [ + - + - ]: 2 : { "createwallet", 4, "avoid_reuse"},
293 [ + - + - ]: 2 : { "createwallet", 5, "descriptors"},
294 [ + - + - ]: 2 : { "createwallet", 6, "load_on_startup"},
295 [ + - + - ]: 2 : { "createwallet", 7, "external_signer"},
296 [ + - + - ]: 2 : { "restorewallet", 2, "load_on_startup"},
297 [ + - + - ]: 2 : { "loadwallet", 1, "load_on_startup"},
298 [ + - + - ]: 2 : { "unloadwallet", 1, "load_on_startup"},
299 [ + - + - ]: 2 : { "getnodeaddresses", 0, "count"},
300 [ + - + - ]: 2 : { "addpeeraddress", 1, "port"},
301 [ + - + - ]: 2 : { "addpeeraddress", 2, "tried"},
302 [ + - + - ]: 2 : { "sendmsgtopeer", 0, "peer_id" },
303 [ + - + - ]: 2 : { "stop", 0, "wait" },
304 [ + - - + ]: 2 : { "addnode", 2, "v2transport" },
305 : : };
306 : : // clang-format on
307 : :
308 : : /** Parse string to UniValue or throw runtime_error if string contains invalid JSON */
309 : 0 : static UniValue Parse(std::string_view raw)
310 : : {
311 : 0 : UniValue parsed;
312 [ # # # # : 0 : if (!parsed.read(raw)) throw std::runtime_error(tfm::format("Error parsing JSON: %s", raw));
# # # # #
# # # ]
313 : 0 : return parsed;
314 [ # # ]: 0 : }
315 : :
316 : : class CRPCConvertTable
317 : : {
318 : : private:
319 : : std::set<std::pair<std::string, int>> members;
320 : : std::set<std::pair<std::string, std::string>> membersByName;
321 : :
322 : : public:
323 : : CRPCConvertTable();
324 : :
325 : : /** Return arg_value as UniValue, and first parse it if it is a non-string parameter */
326 : 0 : UniValue ArgToUniValue(std::string_view arg_value, const std::string& method, int param_idx)
327 : : {
328 [ # # # # : 0 : return members.count({method, param_idx}) > 0 ? Parse(arg_value) : arg_value;
# # # # ]
329 : 0 : }
330 : :
331 : : /** Return arg_value as UniValue, and first parse it if it is a non-string parameter */
332 : 0 : UniValue ArgToUniValue(std::string_view arg_value, const std::string& method, const std::string& param_name)
333 : : {
334 [ # # # # : 0 : return membersByName.count({method, param_name}) > 0 ? Parse(arg_value) : arg_value;
# # # # ]
335 : 0 : }
336 : : };
337 : :
338 : 2 : CRPCConvertTable::CRPCConvertTable()
339 : : {
340 [ + + ]: 546 : for (const auto& cp : vRPCConvertParams) {
341 [ + - ]: 544 : members.emplace(cp.methodName, cp.paramIdx);
342 [ + - ]: 544 : membersByName.emplace(cp.methodName, cp.paramName);
343 : : }
344 : 2 : }
345 : :
346 : 2 : static CRPCConvertTable rpcCvtTable;
347 : :
348 : 0 : UniValue RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams)
349 : : {
350 [ # # ]: 0 : UniValue params(UniValue::VARR);
351 : :
352 [ # # ]: 0 : for (unsigned int idx = 0; idx < strParams.size(); idx++) {
353 : 0 : std::string_view value{strParams[idx]};
354 [ # # # # ]: 0 : params.push_back(rpcCvtTable.ArgToUniValue(value, strMethod, idx));
355 : 0 : }
356 : :
357 : 0 : return params;
358 [ # # ]: 0 : }
359 : :
360 : 0 : UniValue RPCConvertNamedValues(const std::string &strMethod, const std::vector<std::string> &strParams)
361 : : {
362 [ # # ]: 0 : UniValue params(UniValue::VOBJ);
363 [ # # ]: 0 : UniValue positional_args{UniValue::VARR};
364 : :
365 [ # # ]: 0 : for (std::string_view s: strParams) {
366 : 0 : size_t pos = s.find('=');
367 [ # # ]: 0 : if (pos == std::string::npos) {
368 [ # # # # : 0 : positional_args.push_back(rpcCvtTable.ArgToUniValue(s, strMethod, positional_args.size()));
# # ]
369 : 0 : continue;
370 : : }
371 : :
372 [ # # # # ]: 0 : std::string name{s.substr(0, pos)};
373 [ # # ]: 0 : std::string_view value{s.substr(pos+1)};
374 : :
375 : : // Intentionally overwrite earlier named values with later ones as a
376 : : // convenience for scripts and command line users that want to merge
377 : : // options.
378 [ # # # # : 0 : params.pushKV(name, rpcCvtTable.ArgToUniValue(value, strMethod, name));
# # ]
379 : 0 : }
380 : :
381 [ # # # # ]: 0 : if (!positional_args.empty()) {
382 : : // Use pushKVEnd instead of pushKV to avoid overwriting an explicit
383 : : // "args" value with an implicit one. Let the RPC server handle the
384 : : // request as given.
385 [ # # # # : 0 : params.pushKVEnd("args", positional_args);
# # ]
386 : 0 : }
387 : :
388 : 0 : return params;
389 [ # # ]: 0 : }
|