You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

client.cpp 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. // Copyright (c) 2010 Satoshi Nakamoto
  2. // Copyright (c) 2009-2016 The Starwels developers
  3. // Distributed under the MIT software license, see the accompanying
  4. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  5. #include "rpc/client.h"
  6. #include "rpc/protocol.h"
  7. #include "util.h"
  8. #include <set>
  9. #include <stdint.h>
  10. #include <univalue.h>
  11. class CRPCConvertParam
  12. {
  13. public:
  14. std::string methodName; //!< method whose params want conversion
  15. int paramIdx; //!< 0-based idx of param to convert
  16. std::string paramName; //!< parameter name
  17. };
  18. /**
  19. * Specify a (method, idx, name) here if the argument is a non-string RPC
  20. * argument and needs to be converted from JSON.
  21. *
  22. * @note Parameter indexes start from 0.
  23. */
  24. static const CRPCConvertParam vRPCConvertParams[] =
  25. {
  26. { "setmocktime", 0, "timestamp" },
  27. { "generate", 0, "nblocks" },
  28. { "generate", 1, "maxtries" },
  29. { "generatetoaddress", 0, "nblocks" },
  30. { "generatetoaddress", 2, "maxtries" },
  31. { "getnetworkhashps", 0, "nblocks" },
  32. { "getnetworkhashps", 1, "height" },
  33. { "sendtoaddress", 1, "amount" },
  34. { "sendtoaddress", 4, "subtractfeefromamount" },
  35. { "sendtoaddress", 5 , "replaceable" },
  36. { "sendtoaddress", 6 , "conf_target" },
  37. { "settxfee", 0, "amount" },
  38. { "getreceivedbyaddress", 1, "minconf" },
  39. { "getreceivedbyaccount", 1, "minconf" },
  40. { "listreceivedbyaddress", 0, "minconf" },
  41. { "listreceivedbyaddress", 1, "include_empty" },
  42. { "listreceivedbyaddress", 2, "include_watchonly" },
  43. { "listreceivedbyaccount", 0, "minconf" },
  44. { "listreceivedbyaccount", 1, "include_empty" },
  45. { "listreceivedbyaccount", 2, "include_watchonly" },
  46. { "getbalance", 1, "minconf" },
  47. { "getbalance", 2, "include_watchonly" },
  48. { "getblockhash", 0, "height" },
  49. { "waitforblockheight", 0, "height" },
  50. { "waitforblockheight", 1, "timeout" },
  51. { "waitforblock", 1, "timeout" },
  52. { "waitfornewblock", 0, "timeout" },
  53. { "move", 2, "amount" },
  54. { "move", 3, "minconf" },
  55. { "sendfrom", 2, "amount" },
  56. { "sendfrom", 3, "minconf" },
  57. { "listtransactions", 1, "count" },
  58. { "listtransactions", 2, "skip" },
  59. { "listtransactions", 3, "include_watchonly" },
  60. { "listaccounts", 0, "minconf" },
  61. { "listaccounts", 1, "include_watchonly" },
  62. { "walletpassphrase", 1, "timeout" },
  63. { "getblocktemplate", 0, "template_request" },
  64. { "listsinceblock", 1, "target_confirmations" },
  65. { "listsinceblock", 2, "include_watchonly" },
  66. { "listsinceblock", 3, "include_removed" },
  67. { "sendmany", 1, "amounts" },
  68. { "sendmany", 2, "minconf" },
  69. { "sendmany", 4, "subtractfeefrom" },
  70. { "sendmany", 5 , "replaceable" },
  71. { "sendmany", 6 , "conf_target" },
  72. { "addmultisigaddress", 0, "nrequired" },
  73. { "addmultisigaddress", 1, "keys" },
  74. { "createmultisig", 0, "nrequired" },
  75. { "createmultisig", 1, "keys" },
  76. { "listunspent", 0, "minconf" },
  77. { "listunspent", 1, "maxconf" },
  78. { "listunspent", 2, "addresses" },
  79. { "listunspent", 3, "include_unsafe" },
  80. { "listunspent", 4, "query_options" },
  81. { "getblock", 1, "verbosity" },
  82. { "getblock", 1, "verbose" },
  83. { "getblockheader", 1, "verbose" },
  84. { "getchaintxstats", 0, "nblocks" },
  85. { "gettransaction", 1, "include_watchonly" },
  86. { "getrawtransaction", 1, "verbose" },
  87. { "createrawtransaction", 0, "inputs" },
  88. { "createrawtransaction", 1, "outputs" },
  89. { "createrawtransaction", 2, "locktime" },
  90. { "createrawtransaction", 3, "replaceable" },
  91. { "signrawtransaction", 1, "prevtxs" },
  92. { "signrawtransaction", 2, "privkeys" },
  93. { "sendrawtransaction", 1, "allowhighfees" },
  94. { "combinerawtransaction", 0, "txs" },
  95. { "fundrawtransaction", 1, "options" },
  96. { "gettxout", 1, "n" },
  97. { "gettxout", 2, "include_mempool" },
  98. { "gettxoutproof", 0, "txids" },
  99. { "lockunspent", 0, "unlock" },
  100. { "lockunspent", 1, "transactions" },
  101. { "importprivkey", 2, "rescan" },
  102. { "importaddress", 2, "rescan" },
  103. { "importaddress", 3, "p2sh" },
  104. { "importpubkey", 2, "rescan" },
  105. { "importmulti", 0, "requests" },
  106. { "importmulti", 1, "options" },
  107. { "verifychain", 0, "checklevel" },
  108. { "verifychain", 1, "nblocks" },
  109. { "pruneblockchain", 0, "height" },
  110. { "keypoolrefill", 0, "newsize" },
  111. { "getrawmempool", 0, "verbose" },
  112. { "estimatefee", 0, "nblocks" },
  113. { "estimatesmartfee", 0, "conf_target" },
  114. { "estimaterawfee", 0, "conf_target" },
  115. { "estimaterawfee", 1, "threshold" },
  116. { "prioritisetransaction", 1, "dummy" },
  117. { "prioritisetransaction", 2, "fee_delta" },
  118. { "setban", 2, "bantime" },
  119. { "setban", 3, "absolute" },
  120. { "setnetworkactive", 0, "state" },
  121. { "getmempoolancestors", 1, "verbose" },
  122. { "getmempooldescendants", 1, "verbose" },
  123. { "bumpfee", 1, "options" },
  124. { "logging", 0, "include" },
  125. { "logging", 1, "exclude" },
  126. { "disconnectnode", 1, "nodeid" },
  127. // Echo with conversion (For testing only)
  128. { "echojson", 0, "arg0" },
  129. { "echojson", 1, "arg1" },
  130. { "echojson", 2, "arg2" },
  131. { "echojson", 3, "arg3" },
  132. { "echojson", 4, "arg4" },
  133. { "echojson", 5, "arg5" },
  134. { "echojson", 6, "arg6" },
  135. { "echojson", 7, "arg7" },
  136. { "echojson", 8, "arg8" },
  137. { "echojson", 9, "arg9" },
  138. };
  139. class CRPCConvertTable
  140. {
  141. private:
  142. std::set<std::pair<std::string, int>> members;
  143. std::set<std::pair<std::string, std::string>> membersByName;
  144. public:
  145. CRPCConvertTable();
  146. bool convert(const std::string& method, int idx) {
  147. return (members.count(std::make_pair(method, idx)) > 0);
  148. }
  149. bool convert(const std::string& method, const std::string& name) {
  150. return (membersByName.count(std::make_pair(method, name)) > 0);
  151. }
  152. };
  153. CRPCConvertTable::CRPCConvertTable()
  154. {
  155. const unsigned int n_elem =
  156. (sizeof(vRPCConvertParams) / sizeof(vRPCConvertParams[0]));
  157. for (unsigned int i = 0; i < n_elem; i++) {
  158. members.insert(std::make_pair(vRPCConvertParams[i].methodName,
  159. vRPCConvertParams[i].paramIdx));
  160. membersByName.insert(std::make_pair(vRPCConvertParams[i].methodName,
  161. vRPCConvertParams[i].paramName));
  162. }
  163. }
  164. static CRPCConvertTable rpcCvtTable;
  165. /** Non-RFC4627 JSON parser, accepts internal values (such as numbers, true, false, null)
  166. * as well as objects and arrays.
  167. */
  168. UniValue ParseNonRFCJSONValue(const std::string& strVal)
  169. {
  170. UniValue jVal;
  171. if (!jVal.read(std::string("[")+strVal+std::string("]")) ||
  172. !jVal.isArray() || jVal.size()!=1)
  173. throw std::runtime_error(std::string("Error parsing JSON:")+strVal);
  174. return jVal[0];
  175. }
  176. UniValue RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams)
  177. {
  178. UniValue params(UniValue::VARR);
  179. for (unsigned int idx = 0; idx < strParams.size(); idx++) {
  180. const std::string& strVal = strParams[idx];
  181. if (!rpcCvtTable.convert(strMethod, idx)) {
  182. // insert string value directly
  183. params.push_back(strVal);
  184. } else {
  185. // parse string as JSON, insert bool/number/object/etc. value
  186. params.push_back(ParseNonRFCJSONValue(strVal));
  187. }
  188. }
  189. return params;
  190. }
  191. UniValue RPCConvertNamedValues(const std::string &strMethod, const std::vector<std::string> &strParams)
  192. {
  193. UniValue params(UniValue::VOBJ);
  194. for (const std::string &s: strParams) {
  195. size_t pos = s.find("=");
  196. if (pos == std::string::npos) {
  197. throw(std::runtime_error("No '=' in named argument '"+s+"', this needs to be present for every argument (even if it is empty)"));
  198. }
  199. std::string name = s.substr(0, pos);
  200. std::string value = s.substr(pos+1);
  201. if (!rpcCvtTable.convert(strMethod, name)) {
  202. // insert string value directly
  203. params.pushKV(name, value);
  204. } else {
  205. // parse string as JSON, insert bool/number/object/etc. value
  206. params.pushKV(name, ParseNonRFCJSONValue(value));
  207. }
  208. }
  209. return params;
  210. }