LCOV - code coverage report
Current view: top level - src/rpc - client.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 199 202 98.5 %
Date: 2020-09-26 01:30:44 Functions: 14 14 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2020 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 <rpc/client.h>
       7             : #include <util/system.h>
       8             : 
       9             : #include <set>
      10             : #include <stdint.h>
      11             : 
      12      157790 : class CRPCConvertParam
      13             : {
      14             : public:
      15             :     std::string methodName; //!< method whose params want conversion
      16             :     int paramIdx;           //!< 0-based idx of param to convert
      17             :     std::string paramName;  //!< parameter name
      18             : };
      19             : 
      20             : // clang-format off
      21             : /**
      22             :  * Specify a (method, idx, name) here if the argument is a non-string RPC
      23             :  * argument and needs to be converted from JSON.
      24             :  *
      25             :  * @note Parameter indexes start from 0.
      26             :  */
      27       79913 : static const CRPCConvertParam vRPCConvertParams[] =
      28         509 : {
      29         509 :     { "setmocktime", 0, "timestamp" },
      30         509 :     { "mockscheduler", 0, "delta_time" },
      31         509 :     { "utxoupdatepsbt", 1, "descriptors" },
      32         509 :     { "generatetoaddress", 0, "nblocks" },
      33         509 :     { "generatetoaddress", 2, "maxtries" },
      34         509 :     { "generatetodescriptor", 0, "num_blocks" },
      35         509 :     { "generatetodescriptor", 2, "maxtries" },
      36         509 :     { "generateblock", 1, "transactions" },
      37         509 :     { "getnetworkhashps", 0, "nblocks" },
      38         509 :     { "getnetworkhashps", 1, "height" },
      39         509 :     { "sendtoaddress", 1, "amount" },
      40         509 :     { "sendtoaddress", 4, "subtractfeefromamount" },
      41         509 :     { "sendtoaddress", 5 , "replaceable" },
      42         509 :     { "sendtoaddress", 6 , "conf_target" },
      43         509 :     { "sendtoaddress", 8, "avoid_reuse" },
      44         509 :     { "settxfee", 0, "amount" },
      45         509 :     { "sethdseed", 0, "newkeypool" },
      46         509 :     { "getreceivedbyaddress", 1, "minconf" },
      47         509 :     { "getreceivedbylabel", 1, "minconf" },
      48         509 :     { "listreceivedbyaddress", 0, "minconf" },
      49         509 :     { "listreceivedbyaddress", 1, "include_empty" },
      50         509 :     { "listreceivedbyaddress", 2, "include_watchonly" },
      51         509 :     { "listreceivedbylabel", 0, "minconf" },
      52         509 :     { "listreceivedbylabel", 1, "include_empty" },
      53         509 :     { "listreceivedbylabel", 2, "include_watchonly" },
      54         509 :     { "getbalance", 1, "minconf" },
      55         509 :     { "getbalance", 2, "include_watchonly" },
      56         509 :     { "getbalance", 3, "avoid_reuse" },
      57         509 :     { "getblockhash", 0, "height" },
      58         509 :     { "waitforblockheight", 0, "height" },
      59         509 :     { "waitforblockheight", 1, "timeout" },
      60         509 :     { "waitforblock", 1, "timeout" },
      61         509 :     { "waitfornewblock", 0, "timeout" },
      62         509 :     { "listtransactions", 1, "count" },
      63         509 :     { "listtransactions", 2, "skip" },
      64         509 :     { "listtransactions", 3, "include_watchonly" },
      65         509 :     { "walletpassphrase", 1, "timeout" },
      66         509 :     { "getblocktemplate", 0, "template_request" },
      67         509 :     { "listsinceblock", 1, "target_confirmations" },
      68         509 :     { "listsinceblock", 2, "include_watchonly" },
      69         509 :     { "listsinceblock", 3, "include_removed" },
      70         509 :     { "sendmany", 1, "amounts" },
      71         509 :     { "sendmany", 2, "minconf" },
      72         509 :     { "sendmany", 4, "subtractfeefrom" },
      73         509 :     { "sendmany", 5 , "replaceable" },
      74         509 :     { "sendmany", 6 , "conf_target" },
      75         509 :     { "deriveaddresses", 1, "range" },
      76         509 :     { "scantxoutset", 1, "scanobjects" },
      77         509 :     { "addmultisigaddress", 0, "nrequired" },
      78         509 :     { "addmultisigaddress", 1, "keys" },
      79         509 :     { "createmultisig", 0, "nrequired" },
      80         509 :     { "createmultisig", 1, "keys" },
      81         509 :     { "listunspent", 0, "minconf" },
      82         509 :     { "listunspent", 1, "maxconf" },
      83         509 :     { "listunspent", 2, "addresses" },
      84         509 :     { "listunspent", 3, "include_unsafe" },
      85         509 :     { "listunspent", 4, "query_options" },
      86         509 :     { "getblock", 1, "verbosity" },
      87         509 :     { "getblock", 1, "verbose" },
      88         509 :     { "getblockheader", 1, "verbose" },
      89         509 :     { "getchaintxstats", 0, "nblocks" },
      90         509 :     { "gettransaction", 1, "include_watchonly" },
      91         509 :     { "gettransaction", 2, "verbose" },
      92         509 :     { "getrawtransaction", 1, "verbose" },
      93         509 :     { "createrawtransaction", 0, "inputs" },
      94         509 :     { "createrawtransaction", 1, "outputs" },
      95         509 :     { "createrawtransaction", 2, "locktime" },
      96         509 :     { "createrawtransaction", 3, "replaceable" },
      97         509 :     { "decoderawtransaction", 1, "iswitness" },
      98         509 :     { "signrawtransactionwithkey", 1, "privkeys" },
      99         509 :     { "signrawtransactionwithkey", 2, "prevtxs" },
     100         509 :     { "signrawtransactionwithwallet", 1, "prevtxs" },
     101         509 :     { "sendrawtransaction", 1, "maxfeerate" },
     102         509 :     { "testmempoolaccept", 0, "rawtxs" },
     103         509 :     { "testmempoolaccept", 1, "maxfeerate" },
     104         509 :     { "combinerawtransaction", 0, "txs" },
     105         509 :     { "fundrawtransaction", 1, "options" },
     106         509 :     { "fundrawtransaction", 2, "iswitness" },
     107         509 :     { "walletcreatefundedpsbt", 0, "inputs" },
     108         509 :     { "walletcreatefundedpsbt", 1, "outputs" },
     109         509 :     { "walletcreatefundedpsbt", 2, "locktime" },
     110         509 :     { "walletcreatefundedpsbt", 3, "options" },
     111         509 :     { "walletcreatefundedpsbt", 4, "bip32derivs" },
     112         509 :     { "walletprocesspsbt", 1, "sign" },
     113         509 :     { "walletprocesspsbt", 3, "bip32derivs" },
     114         509 :     { "createpsbt", 0, "inputs" },
     115         509 :     { "createpsbt", 1, "outputs" },
     116         509 :     { "createpsbt", 2, "locktime" },
     117         509 :     { "createpsbt", 3, "replaceable" },
     118         509 :     { "combinepsbt", 0, "txs"},
     119         509 :     { "joinpsbts", 0, "txs"},
     120         509 :     { "finalizepsbt", 1, "extract"},
     121         509 :     { "converttopsbt", 1, "permitsigdata"},
     122         509 :     { "converttopsbt", 2, "iswitness"},
     123         509 :     { "gettxout", 1, "n" },
     124         509 :     { "gettxout", 2, "include_mempool" },
     125         509 :     { "gettxoutproof", 0, "txids" },
     126         509 :     { "lockunspent", 0, "unlock" },
     127         509 :     { "lockunspent", 1, "transactions" },
     128         509 :     { "send", 0, "outputs" },
     129         509 :     { "send", 1, "conf_target" },
     130         509 :     { "send", 3, "options" },
     131         509 :     { "importprivkey", 2, "rescan" },
     132         509 :     { "importaddress", 2, "rescan" },
     133         509 :     { "importaddress", 3, "p2sh" },
     134         509 :     { "importpubkey", 2, "rescan" },
     135         509 :     { "importmulti", 0, "requests" },
     136         509 :     { "importmulti", 1, "options" },
     137         509 :     { "importdescriptors", 0, "requests" },
     138         509 :     { "verifychain", 0, "checklevel" },
     139         509 :     { "verifychain", 1, "nblocks" },
     140         509 :     { "getblockstats", 0, "hash_or_height" },
     141         509 :     { "getblockstats", 1, "stats" },
     142         509 :     { "pruneblockchain", 0, "height" },
     143         509 :     { "keypoolrefill", 0, "newsize" },
     144         509 :     { "getrawmempool", 0, "verbose" },
     145         509 :     { "estimatesmartfee", 0, "conf_target" },
     146         509 :     { "estimaterawfee", 0, "conf_target" },
     147         509 :     { "estimaterawfee", 1, "threshold" },
     148         509 :     { "prioritisetransaction", 1, "dummy" },
     149         509 :     { "prioritisetransaction", 2, "fee_delta" },
     150         509 :     { "setban", 2, "bantime" },
     151         509 :     { "setban", 3, "absolute" },
     152         509 :     { "setnetworkactive", 0, "state" },
     153         509 :     { "setwalletflag", 1, "value" },
     154         509 :     { "getmempoolancestors", 1, "verbose" },
     155         509 :     { "getmempooldescendants", 1, "verbose" },
     156         509 :     { "bumpfee", 1, "options" },
     157         509 :     { "psbtbumpfee", 1, "options" },
     158         509 :     { "logging", 0, "include" },
     159         509 :     { "logging", 1, "exclude" },
     160         509 :     { "disconnectnode", 1, "nodeid" },
     161         509 :     { "upgradewallet", 0, "version" },
     162             :     // Echo with conversion (For testing only)
     163         509 :     { "echojson", 0, "arg0" },
     164         509 :     { "echojson", 1, "arg1" },
     165         509 :     { "echojson", 2, "arg2" },
     166         509 :     { "echojson", 3, "arg3" },
     167         509 :     { "echojson", 4, "arg4" },
     168         509 :     { "echojson", 5, "arg5" },
     169         509 :     { "echojson", 6, "arg6" },
     170         509 :     { "echojson", 7, "arg7" },
     171         509 :     { "echojson", 8, "arg8" },
     172         509 :     { "echojson", 9, "arg9" },
     173         509 :     { "rescanblockchain", 0, "start_height"},
     174         509 :     { "rescanblockchain", 1, "stop_height"},
     175         509 :     { "createwallet", 1, "disable_private_keys"},
     176         509 :     { "createwallet", 2, "blank"},
     177         509 :     { "createwallet", 4, "avoid_reuse"},
     178         509 :     { "createwallet", 5, "descriptors"},
     179         509 :     { "createwallet", 6, "load_on_startup"},
     180         509 :     { "loadwallet", 1, "load_on_startup"},
     181         509 :     { "unloadwallet", 1, "load_on_startup"},
     182         509 :     { "getnodeaddresses", 0, "count"},
     183         509 :     { "addpeeraddress", 1, "port"},
     184         509 :     { "stop", 0, "wait" },
     185             : };
     186             : // clang-format on
     187             : 
     188        1018 : class CRPCConvertTable
     189             : {
     190             : private:
     191             :     std::set<std::pair<std::string, int>> members;
     192             :     std::set<std::pair<std::string, std::string>> membersByName;
     193             : 
     194             : public:
     195             :     CRPCConvertTable();
     196             : 
     197         517 :     bool convert(const std::string& method, int idx) {
     198         517 :         return (members.count(std::make_pair(method, idx)) > 0);
     199           0 :     }
     200          57 :     bool convert(const std::string& method, const std::string& name) {
     201          57 :         return (membersByName.count(std::make_pair(method, name)) > 0);
     202           0 :     }
     203             : };
     204             : 
     205        1018 : CRPCConvertTable::CRPCConvertTable()
     206         509 : {
     207             :     const unsigned int n_elem =
     208             :         (sizeof(vRPCConvertParams) / sizeof(vRPCConvertParams[0]));
     209             : 
     210       79404 :     for (unsigned int i = 0; i < n_elem; i++) {
     211      157790 :         members.insert(std::make_pair(vRPCConvertParams[i].methodName,
     212       78895 :                                       vRPCConvertParams[i].paramIdx));
     213      157790 :         membersByName.insert(std::make_pair(vRPCConvertParams[i].methodName,
     214       78895 :                                             vRPCConvertParams[i].paramName));
     215             :     }
     216        1018 : }
     217             : 
     218         509 : static CRPCConvertTable rpcCvtTable;
     219             : 
     220             : /** Non-RFC4627 JSON parser, accepts internal values (such as numbers, true, false, null)
     221             :  * as well as objects and arrays.
     222             :  */
     223         268 : UniValue ParseNonRFCJSONValue(const std::string& strVal)
     224             : {
     225         268 :     UniValue jVal;
     226         522 :     if (!jVal.read(std::string("[")+strVal+std::string("]")) ||
     227         254 :         !jVal.isArray() || jVal.size()!=1)
     228          14 :         throw std::runtime_error(std::string("Error parsing JSON: ") + strVal);
     229         254 :     return jVal[0];
     230         268 : }
     231             : 
     232         491 : UniValue RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams)
     233             : {
     234         498 :     UniValue params(UniValue::VARR);
     235             : 
     236        1001 :     for (unsigned int idx = 0; idx < strParams.size(); idx++) {
     237         517 :         const std::string& strVal = strParams[idx];
     238             : 
     239         517 :         if (!rpcCvtTable.convert(strMethod, idx)) {
     240             :             // insert string value directly
     241         303 :             params.push_back(strVal);
     242             :         } else {
     243             :             // parse string as JSON, insert bool/number/object/etc. value
     244         221 :             params.push_back(ParseNonRFCJSONValue(strVal));
     245             :         }
     246             :     }
     247             : 
     248             :     return params;
     249         491 : }
     250             : 
     251          35 : UniValue RPCConvertNamedValues(const std::string &strMethod, const std::vector<std::string> &strParams)
     252             : {
     253          35 :     UniValue params(UniValue::VOBJ);
     254             : 
     255          92 :     for (const std::string &s: strParams) {
     256          57 :         size_t pos = s.find('=');
     257          57 :         if (pos == std::string::npos) {
     258           0 :             throw(std::runtime_error("No '=' in named argument '"+s+"', this needs to be present for every argument (even if it is empty)"));
     259             :         }
     260             : 
     261          57 :         std::string name = s.substr(0, pos);
     262          57 :         std::string value = s.substr(pos+1);
     263             : 
     264          57 :         if (!rpcCvtTable.convert(strMethod, name)) {
     265             :             // insert string value directly
     266          14 :             params.pushKV(name, value);
     267             :         } else {
     268             :             // parse string as JSON, insert bool/number/object/etc. value
     269          43 :             params.pushKV(name, ParseNonRFCJSONValue(value));
     270             :         }
     271          57 :     }
     272             : 
     273             :     return params;
     274          35 : }

Generated by: LCOV version 1.15