diff options
| author | langerhans <[email protected]> | 2019-06-09 19:49:48 +0200 |
|---|---|---|
| committer | langerhans <[email protected]> | 2019-06-09 19:51:03 +0200 |
| commit | d278efaccdc45e7155147d2c86a50f193eafdc07 (patch) | |
| tree | 05cf92afa059fafff80e460c1619edd5bec231b3 /src/rpc/client.cpp | |
| parent | Revert "Change fPIE to fPIC (#1420)" (#1447) (diff) | |
| parent | Mark 1.14 ready for release (diff) | |
| download | discoin-d278efaccdc45e7155147d2c86a50f193eafdc07.tar.xz discoin-d278efaccdc45e7155147d2c86a50f193eafdc07.zip | |
Merge branch '1.14-branding'
Diffstat (limited to 'src/rpc/client.cpp')
| -rw-r--r-- | src/rpc/client.cpp | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp new file mode 100644 index 000000000..56d149591 --- /dev/null +++ b/src/rpc/client.cpp @@ -0,0 +1,220 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Copyright (c) 2009-2016 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 "rpc/protocol.h" +#include "util.h" + +#include <set> +#include <stdint.h> + +#include <boost/algorithm/string/case_conv.hpp> // for to_lower() +#include <univalue.h> + +using namespace std; + +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 +}; + +/** + * Specifiy 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" }, + { "generate", 0, "nblocks" }, + { "generate", 1, "maxtries" }, + { "generatetoaddress", 0, "nblocks" }, + { "generatetoaddress", 2, "maxtries" }, + { "getnetworkhashps", 0, "nblocks" }, + { "getnetworkhashps", 1, "height" }, + { "sendtoaddress", 1, "amount" }, + { "sendtoaddress", 4, "subtractfeefromamount" }, + { "settxfee", 0, "amount" }, + { "getreceivedbyaddress", 1, "minconf" }, + { "getreceivedbyaccount", 1, "minconf" }, + { "listreceivedbyaddress", 0, "minconf" }, + { "listreceivedbyaddress", 1, "include_empty" }, + { "listreceivedbyaddress", 2, "include_watchonly" }, + { "listreceivedbyaccount", 0, "minconf" }, + { "listreceivedbyaccount", 1, "include_empty" }, + { "listreceivedbyaccount", 2, "include_watchonly" }, + { "getbalance", 1, "minconf" }, + { "getbalance", 2, "include_watchonly" }, + { "getblockhash", 0, "height" }, + { "waitforblockheight", 0, "height" }, + { "waitforblockheight", 1, "timeout" }, + { "waitforblock", 1, "timeout" }, + { "waitfornewblock", 0, "timeout" }, + { "move", 2, "amount" }, + { "move", 3, "minconf" }, + { "sendfrom", 2, "amount" }, + { "sendfrom", 3, "minconf" }, + { "listtransactions", 1, "count" }, + { "listtransactions", 2, "skip" }, + { "listtransactions", 3, "include_watchonly" }, + { "listaccounts", 0, "minconf" }, + { "listaccounts", 1, "include_watchonly" }, + { "walletpassphrase", 1, "timeout" }, + { "getblocktemplate", 0, "template_request" }, + { "listsinceblock", 1, "target_confirmations" }, + { "listsinceblock", 2, "include_watchonly" }, + { "sendmany", 1, "amounts" }, + { "sendmany", 2, "minconf" }, + { "sendmany", 4, "subtractfeefrom" }, + { "addmultisigaddress", 0, "nrequired" }, + { "addmultisigaddress", 1, "keys" }, + { "createmultisig", 0, "nrequired" }, + { "createmultisig", 1, "keys" }, + { "listunspent", 0, "minconf" }, + { "listunspent", 1, "maxconf" }, + { "listunspent", 2, "addresses" }, + { "getblock", 1, "verbose" }, + { "getblockheader", 1, "verbose" }, + { "gettransaction", 1, "include_watchonly" }, + { "getrawtransaction", 1, "verbose" }, + { "createrawtransaction", 0, "inputs" }, + { "createrawtransaction", 1, "outputs" }, + { "createrawtransaction", 2, "locktime" }, + { "signrawtransaction", 1, "prevtxs" }, + { "signrawtransaction", 2, "privkeys" }, + { "sendrawtransaction", 1, "allowhighfees" }, + { "fundrawtransaction", 1, "options" }, + { "gettxout", 1, "n" }, + { "gettxout", 2, "include_mempool" }, + { "gettxoutproof", 0, "txids" }, + { "lockunspent", 0, "unlock" }, + { "lockunspent", 1, "transactions" }, + { "importprivkey", 2, "rescan" }, + { "importaddress", 2, "rescan" }, + { "importaddress", 3, "p2sh" }, + { "importpubkey", 2, "rescan" }, + { "importmulti", 0, "requests" }, + { "importmulti", 1, "options" }, + { "verifychain", 0, "checklevel" }, + { "verifychain", 1, "nblocks" }, + { "pruneblockchain", 0, "height" }, + { "keypoolrefill", 0, "newsize" }, + { "getrawmempool", 0, "verbose" }, + { "estimatefee", 0, "nblocks" }, + { "estimatepriority", 0, "nblocks" }, + { "estimatesmartfee", 0, "nblocks" }, + { "estimatesmartpriority", 0, "nblocks" }, + { "prioritisetransaction", 1, "priority_delta" }, + { "prioritisetransaction", 2, "fee_delta" }, + { "setban", 2, "bantime" }, + { "setban", 3, "absolute" }, + { "setnetworkactive", 0, "state" }, + { "getmempoolancestors", 1, "verbose" }, + { "getmempooldescendants", 1, "verbose" }, + { "bumpfee", 1, "options" }, + // 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" }, +}; + +class 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 runtime_error(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; +} |