git / moonbite-core / src/rpc/client.cpp · raw

// Copyright (c) 2010 Satoshi Nakamoto// Copyright (c) 2009-2020 The Bitcoin Core developers// Distributed under the MIT software license, see the accompanying// file COPYING or http://www.opensource.org/licenses/mit-license.php.#include <rpc/client.h>#include <util/system.h>#include <set>#include <stdint.h>class CRPCConvertParam{public:    std::string methodName; //!< method whose params want conversion    int paramIdx;           //!< 0-based idx of param to convert    std::string paramName;  //!< parameter name};// clang-format off/** * Specify a (method, idx, name) here if the argument is a non-string RPC * argument and needs to be converted from JSON. * * @note Parameter indexes start from 0. */static const CRPCConvertParam vRPCConvertParams[] ={    { "setmocktime", 0, "timestamp" },    { "mockscheduler", 0, "delta_time" },    { "utxoupdatepsbt", 1, "descriptors" },    { "generatetoaddress", 0, "nblocks" },    { "generatetoaddress", 2, "maxtries" },    { "generatetodescriptor", 0, "num_blocks" },    { "generatetodescriptor", 2, "maxtries" },    { "generateblock", 1, "transactions" },    { "getnetworkhashps", 0, "nblocks" },    { "getnetworkhashps", 1, "height" },    { "sendtoaddress", 1, "amount" },    { "sendtoaddress", 4, "subtractfeefromamount" },    { "sendtoaddress", 5 , "replaceable" },    { "sendtoaddress", 6 , "conf_target" },    { "sendtoaddress", 8, "avoid_reuse" },    { "sendtoaddress", 9, "fee_rate"},    { "sendtoaddress", 10, "verbose"},    { "settxfee", 0, "amount" },    { "sethdseed", 0, "newkeypool" },    { "getreceivedbyaddress", 1, "minconf" },    { "getreceivedbylabel", 1, "minconf" },    { "listreceivedbyaddress", 0, "minconf" },    { "listreceivedbyaddress", 1, "include_empty" },    { "listreceivedbyaddress", 2, "include_watchonly" },    { "listreceivedbylabel", 0, "minconf" },    { "listreceivedbylabel", 1, "include_empty" },    { "listreceivedbylabel", 2, "include_watchonly" },    { "getbalance", 1, "minconf" },    { "getbalance", 2, "include_watchonly" },    { "getbalance", 3, "avoid_reuse" },    { "getblockhash", 0, "height" },    { "waitforblockheight", 0, "height" },    { "waitforblockheight", 1, "timeout" },    { "waitforblock", 1, "timeout" },    { "waitfornewblock", 0, "timeout" },    { "listtransactions", 1, "count" },    { "listtransactions", 2, "skip" },    { "listtransactions", 3, "include_watchonly" },    { "walletpassphrase", 1, "timeout" },    { "getblocktemplate", 0, "template_request" },    { "listsinceblock", 1, "target_confirmations" },    { "listsinceblock", 2, "include_watchonly" },    { "listsinceblock", 3, "include_removed" },    { "sendmany", 1, "amounts" },    { "sendmany", 2, "minconf" },    { "sendmany", 4, "subtractfeefrom" },    { "sendmany", 5 , "replaceable" },    { "sendmany", 6 , "conf_target" },    { "sendmany", 8, "fee_rate"},    { "sendmany", 9, "verbose" },    { "deriveaddresses", 1, "range" },    { "scantxoutset", 1, "scanobjects" },    { "addmultisigaddress", 0, "nrequired" },    { "addmultisigaddress", 1, "keys" },    { "createmultisig", 0, "nrequired" },    { "createmultisig", 1, "keys" },    { "listunspent", 0, "minconf" },    { "listunspent", 1, "maxconf" },    { "listunspent", 2, "addresses" },    { "listunspent", 3, "include_unsafe" },    { "listunspent", 4, "query_options" },    { "getblock", 1, "verbosity" },    { "getblock", 1, "verbose" },    { "getblockheader", 1, "verbose" },    { "getchaintxstats", 0, "nblocks" },    { "gettransaction", 1, "include_watchonly" },    { "gettransaction", 2, "verbose" },    { "getrawtransaction", 1, "verbose" },    { "createrawtransaction", 0, "inputs" },    { "createrawtransaction", 1, "outputs" },    { "createrawtransaction", 2, "locktime" },    { "createrawtransaction", 3, "replaceable" },    { "decoderawtransaction", 1, "iswitness" },    { "signrawtransactionwithkey", 1, "privkeys" },    { "signrawtransactionwithkey", 2, "prevtxs" },    { "signrawtransactionwithwallet", 1, "prevtxs" },    { "sendrawtransaction", 1, "maxfeerate" },    { "testmempoolaccept", 0, "rawtxs" },    { "testmempoolaccept", 1, "maxfeerate" },    { "combinerawtransaction", 0, "txs" },    { "fundrawtransaction", 1, "options" },    { "fundrawtransaction", 2, "iswitness" },    { "walletcreatefundedpsbt", 0, "inputs" },    { "walletcreatefundedpsbt", 1, "outputs" },    { "walletcreatefundedpsbt", 2, "locktime" },    { "walletcreatefundedpsbt", 3, "options" },    { "walletcreatefundedpsbt", 4, "bip32derivs" },    { "walletprocesspsbt", 1, "sign" },    { "walletprocesspsbt", 3, "bip32derivs" },    { "createpsbt", 0, "inputs" },    { "createpsbt", 1, "outputs" },    { "createpsbt", 2, "locktime" },    { "createpsbt", 3, "replaceable" },    { "combinepsbt", 0, "txs"},    { "joinpsbts", 0, "txs"},    { "finalizepsbt", 1, "extract"},    { "converttopsbt", 1, "permitsigdata"},    { "converttopsbt", 2, "iswitness"},    { "gettxout", 1, "n" },    { "gettxout", 2, "include_mempool" },    { "gettxoutproof", 0, "txids" },    { "lockunspent", 0, "unlock" },    { "lockunspent", 1, "transactions" },    { "send", 0, "outputs" },    { "send", 1, "conf_target" },    { "send", 3, "fee_rate"},    { "send", 4, "options" },    { "importprivkey", 2, "rescan" },    { "importaddress", 2, "rescan" },    { "importaddress", 3, "p2sh" },    { "importpubkey", 2, "rescan" },    { "importmulti", 0, "requests" },    { "importmulti", 1, "options" },    { "importdescriptors", 0, "requests" },    { "verifychain", 0, "checklevel" },    { "verifychain", 1, "nblocks" },    { "getblockstats", 0, "hash_or_height" },    { "getblockstats", 1, "stats" },    { "pruneblockchain", 0, "height" },    { "keypoolrefill", 0, "newsize" },    { "getrawmempool", 0, "verbose" },    { "getrawmempool", 1, "mempool_sequence" },    { "estimatesmartfee", 0, "conf_target" },    { "estimaterawfee", 0, "conf_target" },    { "estimaterawfee", 1, "threshold" },    { "prioritisetransaction", 1, "dummy" },    { "prioritisetransaction", 2, "fee_delta" },    { "setban", 2, "bantime" },    { "setban", 3, "absolute" },    { "setnetworkactive", 0, "state" },    { "setwalletflag", 1, "value" },    { "getmempoolancestors", 1, "verbose" },    { "getmempooldescendants", 1, "verbose" },    { "bumpfee", 1, "options" },    { "psbtbumpfee", 1, "options" },    { "logging", 0, "include" },    { "logging", 1, "exclude" },    { "disconnectnode", 1, "nodeid" },    { "upgradewallet", 0, "version" },    // Echo with conversion (For testing only)    { "echojson", 0, "arg0" },    { "echojson", 1, "arg1" },    { "echojson", 2, "arg2" },    { "echojson", 3, "arg3" },    { "echojson", 4, "arg4" },    { "echojson", 5, "arg5" },    { "echojson", 6, "arg6" },    { "echojson", 7, "arg7" },    { "echojson", 8, "arg8" },    { "echojson", 9, "arg9" },    { "rescanblockchain", 0, "start_height"},    { "rescanblockchain", 1, "stop_height"},    { "createwallet", 1, "disable_private_keys"},    { "createwallet", 2, "blank"},    { "createwallet", 4, "avoid_reuse"},    { "createwallet", 5, "descriptors"},    { "createwallet", 6, "load_on_startup"},    { "loadwallet", 1, "load_on_startup"},    { "unloadwallet", 1, "load_on_startup"},    { "getnodeaddresses", 0, "count"},    { "addpeeraddress", 1, "port"},    { "stop", 0, "wait" },    { "createvault", 2, "delay_blocks" },    { "sos", 1, "amount" },    { "unvault", 2, "vout" },    { "unvault", 5, "fee" },};// clang-format onclass CRPCConvertTable{private:    std::set<std::pair<std::string, int>> members;    std::set<std::pair<std::string, std::string>> membersByName;public:    CRPCConvertTable();    bool convert(const std::string& method, int idx) {        return (members.count(std::make_pair(method, idx)) > 0);    }    bool convert(const std::string& method, const std::string& name) {        return (membersByName.count(std::make_pair(method, name)) > 0);    }};CRPCConvertTable::CRPCConvertTable(){    const unsigned int n_elem =        (sizeof(vRPCConvertParams) / sizeof(vRPCConvertParams[0]));    for (unsigned int i = 0; i < n_elem; i++) {        members.insert(std::make_pair(vRPCConvertParams[i].methodName,                                      vRPCConvertParams[i].paramIdx));        membersByName.insert(std::make_pair(vRPCConvertParams[i].methodName,                                            vRPCConvertParams[i].paramName));    }}static CRPCConvertTable rpcCvtTable;/** Non-RFC4627 JSON parser, accepts internal values (such as numbers, true, false, null) * as well as objects and arrays. */UniValue ParseNonRFCJSONValue(const std::string& strVal){    UniValue jVal;    if (!jVal.read(std::string("[")+strVal+std::string("]")) ||        !jVal.isArray() || jVal.size()!=1)        throw std::runtime_error(std::string("Error parsing JSON: ") + strVal);    return jVal[0];}UniValue RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams){    UniValue params(UniValue::VARR);    for (unsigned int idx = 0; idx < strParams.size(); idx++) {        const std::string& strVal = strParams[idx];        if (!rpcCvtTable.convert(strMethod, idx)) {            // insert string value directly            params.push_back(strVal);        } else {            // parse string as JSON, insert bool/number/object/etc. value            params.push_back(ParseNonRFCJSONValue(strVal));        }    }    return params;}UniValue RPCConvertNamedValues(const std::string &strMethod, const std::vector<std::string> &strParams){    UniValue params(UniValue::VOBJ);    for (const std::string &s: strParams) {        size_t pos = s.find('=');        if (pos == std::string::npos) {            throw(std::runtime_error("No '=' in named argument '"+s+"', this needs to be present for every argument (even if it is empty)"));        }        std::string name = s.substr(0, pos);        std::string value = s.substr(pos+1);        if (!rpcCvtTable.convert(strMethod, name)) {            // insert string value directly            params.pushKV(name, value);        } else {            // parse string as JSON, insert bool/number/object/etc. value            params.pushKV(name, ParseNonRFCJSONValue(value));        }    }    return params;}