2013-11-20 14:18:57 +01:00
|
|
|
// Copyright (c) 2010 Satoshi Nakamoto
|
2021-12-30 19:36:57 +02:00
|
|
|
// Copyright (c) 2009-2021 The Bitcoin Core developers
|
2014-11-20 10:19:29 +08:00
|
|
|
// Distributed under the MIT software license, see the accompanying
|
2013-11-20 14:18:57 +01:00
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
2017-11-10 13:57:53 +13:00
|
|
|
#include <rpc/client.h>
|
2018-10-22 15:51:11 -07:00
|
|
|
#include <util/system.h>
|
2013-11-20 14:18:57 +01:00
|
|
|
|
2014-09-14 12:43:56 +02:00
|
|
|
#include <set>
|
2013-11-20 14:18:57 +01:00
|
|
|
#include <stdint.h>
|
|
|
|
|
2014-06-26 22:12:36 -04:00
|
|
|
class CRPCConvertParam
|
2013-11-20 14:18:57 +01:00
|
|
|
{
|
2014-06-26 22:12:36 -04:00
|
|
|
public:
|
2016-04-03 11:49:36 +02:00
|
|
|
std::string methodName; //!< method whose params want conversion
|
|
|
|
int paramIdx; //!< 0-based idx of param to convert
|
2016-11-22 14:56:29 +01:00
|
|
|
std::string paramName; //!< parameter name
|
2014-06-26 22:12:36 -04:00
|
|
|
};
|
|
|
|
|
2018-08-20 14:19:43 +02:00
|
|
|
// clang-format off
|
2016-11-22 14:56:29 +01:00
|
|
|
/**
|
2017-02-06 15:16:18 +01:00
|
|
|
* Specify a (method, idx, name) here if the argument is a non-string RPC
|
2016-11-22 14:56:29 +01:00
|
|
|
* argument and needs to be converted from JSON.
|
|
|
|
*
|
|
|
|
* @note Parameter indexes start from 0.
|
|
|
|
*/
|
2014-06-26 22:12:36 -04:00
|
|
|
static const CRPCConvertParam vRPCConvertParams[] =
|
|
|
|
{
|
2016-11-22 14:56:29 +01:00
|
|
|
{ "setmocktime", 0, "timestamp" },
|
2020-02-12 11:12:20 -08:00
|
|
|
{ "mockscheduler", 0, "delta_time" },
|
2019-07-02 18:34:18 +01:00
|
|
|
{ "utxoupdatepsbt", 1, "descriptors" },
|
2016-11-22 14:56:29 +01:00
|
|
|
{ "generatetoaddress", 0, "nblocks" },
|
|
|
|
{ "generatetoaddress", 2, "maxtries" },
|
2019-09-23 14:27:23 -04:00
|
|
|
{ "generatetodescriptor", 0, "num_blocks" },
|
|
|
|
{ "generatetodescriptor", 2, "maxtries" },
|
2020-03-27 11:00:10 -04:00
|
|
|
{ "generateblock", 1, "transactions" },
|
2016-11-22 14:56:29 +01:00
|
|
|
{ "getnetworkhashps", 0, "nblocks" },
|
|
|
|
{ "getnetworkhashps", 1, "height" },
|
|
|
|
{ "sendtoaddress", 1, "amount" },
|
|
|
|
{ "sendtoaddress", 4, "subtractfeefromamount" },
|
2017-06-14 15:15:40 -04:00
|
|
|
{ "sendtoaddress", 5 , "replaceable" },
|
|
|
|
{ "sendtoaddress", 6 , "conf_target" },
|
2018-09-11 15:53:36 +09:00
|
|
|
{ "sendtoaddress", 8, "avoid_reuse" },
|
2020-11-04 13:13:17 +01:00
|
|
|
{ "sendtoaddress", 9, "fee_rate"},
|
|
|
|
{ "sendtoaddress", 10, "verbose"},
|
2016-11-22 14:56:29 +01:00
|
|
|
{ "settxfee", 0, "amount" },
|
2017-09-12 14:01:12 -07:00
|
|
|
{ "sethdseed", 0, "newkeypool" },
|
2016-11-22 14:56:29 +01:00
|
|
|
{ "getreceivedbyaddress", 1, "minconf" },
|
2021-12-06 12:30:58 -05:00
|
|
|
{ "getreceivedbyaddress", 2, "include_immature_coinbase" },
|
2017-10-20 13:27:55 -04:00
|
|
|
{ "getreceivedbylabel", 1, "minconf" },
|
2021-12-06 12:30:58 -05:00
|
|
|
{ "getreceivedbylabel", 2, "include_immature_coinbase" },
|
2016-11-22 14:56:29 +01:00
|
|
|
{ "listreceivedbyaddress", 0, "minconf" },
|
|
|
|
{ "listreceivedbyaddress", 1, "include_empty" },
|
|
|
|
{ "listreceivedbyaddress", 2, "include_watchonly" },
|
2021-12-06 12:30:58 -05:00
|
|
|
{ "listreceivedbyaddress", 4, "include_immature_coinbase" },
|
2017-10-20 13:27:55 -04:00
|
|
|
{ "listreceivedbylabel", 0, "minconf" },
|
|
|
|
{ "listreceivedbylabel", 1, "include_empty" },
|
|
|
|
{ "listreceivedbylabel", 2, "include_watchonly" },
|
2021-12-06 12:30:58 -05:00
|
|
|
{ "listreceivedbylabel", 3, "include_immature_coinbase" },
|
2016-11-22 14:56:29 +01:00
|
|
|
{ "getbalance", 1, "minconf" },
|
|
|
|
{ "getbalance", 2, "include_watchonly" },
|
2018-09-11 15:53:36 +09:00
|
|
|
{ "getbalance", 3, "avoid_reuse" },
|
2021-12-10 20:12:05 +07:00
|
|
|
{ "getblockfrompeer", 1, "peer_id" },
|
2016-12-09 17:06:42 +00:00
|
|
|
{ "getblockhash", 0, "height" },
|
2016-11-22 14:56:29 +01:00
|
|
|
{ "waitforblockheight", 0, "height" },
|
|
|
|
{ "waitforblockheight", 1, "timeout" },
|
|
|
|
{ "waitforblock", 1, "timeout" },
|
|
|
|
{ "waitfornewblock", 0, "timeout" },
|
|
|
|
{ "listtransactions", 1, "count" },
|
2016-12-09 17:06:42 +00:00
|
|
|
{ "listtransactions", 2, "skip" },
|
2016-11-22 14:56:29 +01:00
|
|
|
{ "listtransactions", 3, "include_watchonly" },
|
|
|
|
{ "walletpassphrase", 1, "timeout" },
|
|
|
|
{ "getblocktemplate", 0, "template_request" },
|
|
|
|
{ "listsinceblock", 1, "target_confirmations" },
|
|
|
|
{ "listsinceblock", 2, "include_watchonly" },
|
2017-01-24 14:27:22 +09:00
|
|
|
{ "listsinceblock", 3, "include_removed" },
|
2016-11-22 14:56:29 +01:00
|
|
|
{ "sendmany", 1, "amounts" },
|
|
|
|
{ "sendmany", 2, "minconf" },
|
|
|
|
{ "sendmany", 4, "subtractfeefrom" },
|
2017-06-14 15:15:40 -04:00
|
|
|
{ "sendmany", 5 , "replaceable" },
|
|
|
|
{ "sendmany", 6 , "conf_target" },
|
2020-11-04 13:13:17 +01:00
|
|
|
{ "sendmany", 8, "fee_rate"},
|
|
|
|
{ "sendmany", 9, "verbose" },
|
2019-03-01 13:45:16 +01:00
|
|
|
{ "deriveaddresses", 1, "range" },
|
2018-01-15 20:33:59 -10:00
|
|
|
{ "scantxoutset", 1, "scanobjects" },
|
2016-11-22 14:56:29 +01:00
|
|
|
{ "addmultisigaddress", 0, "nrequired" },
|
|
|
|
{ "addmultisigaddress", 1, "keys" },
|
|
|
|
{ "createmultisig", 0, "nrequired" },
|
|
|
|
{ "createmultisig", 1, "keys" },
|
|
|
|
{ "listunspent", 0, "minconf" },
|
|
|
|
{ "listunspent", 1, "maxconf" },
|
|
|
|
{ "listunspent", 2, "addresses" },
|
2017-06-19 11:48:57 +09:00
|
|
|
{ "listunspent", 3, "include_unsafe" },
|
2017-03-07 18:17:32 +00:00
|
|
|
{ "listunspent", 4, "query_options" },
|
2017-04-10 09:28:56 -04:00
|
|
|
{ "getblock", 1, "verbosity" },
|
2017-07-05 12:09:58 +01:00
|
|
|
{ "getblock", 1, "verbose" },
|
2016-11-22 14:56:29 +01:00
|
|
|
{ "getblockheader", 1, "verbose" },
|
2017-02-09 17:24:30 -08:00
|
|
|
{ "getchaintxstats", 0, "nblocks" },
|
2016-11-22 14:56:29 +01:00
|
|
|
{ "gettransaction", 1, "include_watchonly" },
|
2019-09-13 22:31:11 +03:00
|
|
|
{ "gettransaction", 2, "verbose" },
|
2016-11-22 14:56:29 +01:00
|
|
|
{ "getrawtransaction", 1, "verbose" },
|
2017-03-26 12:08:44 +02:00
|
|
|
{ "createrawtransaction", 0, "inputs" },
|
2016-11-22 14:56:29 +01:00
|
|
|
{ "createrawtransaction", 1, "outputs" },
|
|
|
|
{ "createrawtransaction", 2, "locktime" },
|
2017-06-28 17:49:04 -04:00
|
|
|
{ "createrawtransaction", 3, "replaceable" },
|
2017-08-28 18:00:21 +12:00
|
|
|
{ "decoderawtransaction", 1, "iswitness" },
|
2017-06-12 12:23:02 -07:00
|
|
|
{ "signrawtransactionwithkey", 1, "privkeys" },
|
|
|
|
{ "signrawtransactionwithkey", 2, "prevtxs" },
|
|
|
|
{ "signrawtransactionwithwallet", 1, "prevtxs" },
|
2018-06-27 17:21:07 +09:00
|
|
|
{ "sendrawtransaction", 1, "maxfeerate" },
|
2017-11-17 12:54:39 -05:00
|
|
|
{ "testmempoolaccept", 0, "rawtxs" },
|
2019-02-14 17:07:29 +09:00
|
|
|
{ "testmempoolaccept", 1, "maxfeerate" },
|
2017-06-09 22:38:06 -07:00
|
|
|
{ "combinerawtransaction", 0, "txs" },
|
2016-11-22 14:56:29 +01:00
|
|
|
{ "fundrawtransaction", 1, "options" },
|
2017-08-28 18:00:21 +12:00
|
|
|
{ "fundrawtransaction", 2, "iswitness" },
|
2018-06-28 19:05:05 -07:00
|
|
|
{ "walletcreatefundedpsbt", 0, "inputs" },
|
|
|
|
{ "walletcreatefundedpsbt", 1, "outputs" },
|
|
|
|
{ "walletcreatefundedpsbt", 2, "locktime" },
|
2018-08-14 21:12:33 -04:00
|
|
|
{ "walletcreatefundedpsbt", 3, "options" },
|
|
|
|
{ "walletcreatefundedpsbt", 4, "bip32derivs" },
|
2018-06-28 19:05:05 -07:00
|
|
|
{ "walletprocesspsbt", 1, "sign" },
|
|
|
|
{ "walletprocesspsbt", 3, "bip32derivs" },
|
2021-07-20 21:24:56 -04:00
|
|
|
{ "walletprocesspsbt", 4, "finalize" },
|
2018-06-28 19:04:40 -07:00
|
|
|
{ "createpsbt", 0, "inputs" },
|
|
|
|
{ "createpsbt", 1, "outputs" },
|
|
|
|
{ "createpsbt", 2, "locktime" },
|
|
|
|
{ "createpsbt", 3, "replaceable" },
|
|
|
|
{ "combinepsbt", 0, "txs"},
|
2018-07-20 18:24:16 -07:00
|
|
|
{ "joinpsbts", 0, "txs"},
|
2018-06-28 19:04:40 -07:00
|
|
|
{ "finalizepsbt", 1, "extract"},
|
|
|
|
{ "converttopsbt", 1, "permitsigdata"},
|
|
|
|
{ "converttopsbt", 2, "iswitness"},
|
2016-11-22 14:56:29 +01:00
|
|
|
{ "gettxout", 1, "n" },
|
|
|
|
{ "gettxout", 2, "include_mempool" },
|
|
|
|
{ "gettxoutproof", 0, "txids" },
|
2020-08-22 20:21:20 +02:00
|
|
|
{ "gettxoutsetinfo", 1, "hash_or_height" },
|
2021-02-28 19:27:00 +01:00
|
|
|
{ "gettxoutsetinfo", 2, "use_index"},
|
2016-11-22 14:56:29 +01:00
|
|
|
{ "lockunspent", 0, "unlock" },
|
|
|
|
{ "lockunspent", 1, "transactions" },
|
2021-09-23 00:18:39 +12:00
|
|
|
{ "lockunspent", 2, "persistent" },
|
2020-08-07 17:36:36 +02:00
|
|
|
{ "send", 0, "outputs" },
|
|
|
|
{ "send", 1, "conf_target" },
|
2020-11-04 13:13:17 +01:00
|
|
|
{ "send", 3, "fee_rate"},
|
|
|
|
{ "send", 4, "options" },
|
Add sendall RPC née sweep
_Motivation_
Currently, the wallet uses a fSubtractFeeAmount (SFFO) flag on the
recipients objects for all forms of sending calls. According to the
commit discussion, this flag was chiefly introduced to permit sweeping
without manually calculating the fees of transactions. However, the flag
leads to unintuitive behavior and makes it more complicated to test
many wallet RPCs exhaustively. We proposed to introduce a dedicated
`sendall` RPC with the intention to cover this functionality.
Since the proposal, it was discovered in further discussion that our
proposed `sendall` rpc and SFFO have subtly different scopes of
operation.
• sendall:
Use _specific UTXOs_ to pay a destination the remainder after fees.
• SFFO:
Use a _specific budget_ to pay an address the remainder after fees.
While `sendall` will simplify cases of spending from specific UTXOs,
emptying a wallet, or burning dust, we realized that there are some
cases in which SFFO is used to pay other parties from a limited budget,
which can often lead to the creation of change outputs. This cannot be
easily replicated using `sendall` as it would require manual computation
of the appropriate change amount.
As such, sendall cannot replace all uses of SFFO, but it still has a
different use case and will aid in simplifying some wallet calls and
numerous wallet tests.
_Sendall call details_
The proposed sendall call builds a transaction from a specific subset of
the wallet's UTXO pool (by default all of them) and assigns the funds to
one or more receivers. Receivers can either be specified with a specific
amount or receive an equal share of the remaining unassigned funds. At
least one recipient must be provided without assigned amount to collect
the remainder. The `sendall` call will never create change. The call has
a `send_max` option that changes the default behavior of spending all
UTXOs ("no UTXO left behind"), to maximizing the output amount of the
transaction by skipping uneconomic UTXOs. The `send_max` option is
incompatible with providing a specific set of inputs.
2022-01-12 13:59:41 -05:00
|
|
|
{ "sendall", 0, "recipients" },
|
|
|
|
{ "sendall", 1, "conf_target" },
|
|
|
|
{ "sendall", 3, "fee_rate"},
|
|
|
|
{ "sendall", 4, "options" },
|
2016-11-22 14:56:29 +01:00
|
|
|
{ "importprivkey", 2, "rescan" },
|
|
|
|
{ "importaddress", 2, "rescan" },
|
|
|
|
{ "importaddress", 3, "p2sh" },
|
|
|
|
{ "importpubkey", 2, "rescan" },
|
|
|
|
{ "importmulti", 0, "requests" },
|
|
|
|
{ "importmulti", 1, "options" },
|
2019-08-01 15:08:47 -07:00
|
|
|
{ "importdescriptors", 0, "requests" },
|
2021-06-24 08:35:23 +02:00
|
|
|
{ "listdescriptors", 0, "private" },
|
2016-11-22 14:56:29 +01:00
|
|
|
{ "verifychain", 0, "checklevel" },
|
|
|
|
{ "verifychain", 1, "nblocks" },
|
2017-06-04 00:25:55 +02:00
|
|
|
{ "getblockstats", 0, "hash_or_height" },
|
|
|
|
{ "getblockstats", 1, "stats" },
|
2016-11-29 12:39:19 -05:00
|
|
|
{ "pruneblockchain", 0, "height" },
|
2016-11-22 14:56:29 +01:00
|
|
|
{ "keypoolrefill", 0, "newsize" },
|
|
|
|
{ "getrawmempool", 0, "verbose" },
|
Add 'sequence' zmq publisher to track all block (dis)connects, mempool deltas
Using the zmq notifications to avoid excessive mempool polling can be difficult
given the current notifications available. It announces all transactions
being added to mempool or included in blocks, but announces no evictions
and gives no indication if the transaction is in the mempool or a block.
Block notifications for zmq are also substandard, in that it only announces
block tips, while all block transactions are still announced.
This commit adds a unified stream which can be used to closely track mempool:
1) getrawmempool to fill out mempool knowledge
2) if txhash is announced, add or remove from set
based on add/remove flag
3) if blockhash is announced, get block txn list,
remove from those transactions local view of mempool
4) if we drop a sequence number, go to (1)
The mempool sequence number starts at the value 1, and
increments each time a transaction enters the mempool,
or is evicted from the mempool for any reason, including
block inclusion. The mempool sequence number is published
via ZMQ for any transaction-related notification.
These features allow for ZMQ/RPC consumer to track mempool
state in a more exacting way, without unnecesarily polling
getrawmempool. See interface_zmq.py::test_mempool_sync for
example usage.
2020-09-04 11:55:58 -04:00
|
|
|
{ "getrawmempool", 1, "mempool_sequence" },
|
2017-09-07 19:15:45 +02:00
|
|
|
{ "estimatesmartfee", 0, "conf_target" },
|
2017-09-07 18:16:34 +02:00
|
|
|
{ "estimaterawfee", 0, "conf_target" },
|
2017-01-24 16:30:03 -05:00
|
|
|
{ "estimaterawfee", 1, "threshold" },
|
2017-06-06 10:13:17 -04:00
|
|
|
{ "prioritisetransaction", 1, "dummy" },
|
2017-04-21 16:41:01 +00:00
|
|
|
{ "prioritisetransaction", 2, "fee_delta" },
|
2016-11-22 14:56:29 +01:00
|
|
|
{ "setban", 2, "bantime" },
|
|
|
|
{ "setban", 3, "absolute" },
|
|
|
|
{ "setnetworkactive", 0, "state" },
|
2018-09-13 13:35:10 +09:00
|
|
|
{ "setwalletflag", 1, "value" },
|
2016-11-22 14:56:29 +01:00
|
|
|
{ "getmempoolancestors", 1, "verbose" },
|
|
|
|
{ "getmempooldescendants", 1, "verbose" },
|
2022-04-25 10:29:25 +02:00
|
|
|
{ "gettxspendingprevout", 0, "outputs" },
|
2016-12-09 13:45:27 -05:00
|
|
|
{ "bumpfee", 1, "options" },
|
2020-04-13 14:48:03 -04:00
|
|
|
{ "psbtbumpfee", 1, "options" },
|
2017-04-03 13:39:11 -04:00
|
|
|
{ "logging", 0, "include" },
|
|
|
|
{ "logging", 1, "exclude" },
|
2017-04-03 10:03:00 -04:00
|
|
|
{ "disconnectnode", 1, "nodeid" },
|
2019-04-06 12:56:06 -04:00
|
|
|
{ "upgradewallet", 0, "version" },
|
2016-11-22 14:56:29 +01:00
|
|
|
// 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" },
|
2015-11-19 16:05:37 +01:00
|
|
|
{ "rescanblockchain", 0, "start_height"},
|
|
|
|
{ "rescanblockchain", 1, "stop_height"},
|
2018-06-13 20:35:41 +02:00
|
|
|
{ "createwallet", 1, "disable_private_keys"},
|
2019-02-06 21:26:55 -05:00
|
|
|
{ "createwallet", 2, "blank"},
|
2018-09-11 15:53:36 +09:00
|
|
|
{ "createwallet", 4, "avoid_reuse"},
|
2019-07-11 18:21:21 -04:00
|
|
|
{ "createwallet", 5, "descriptors"},
|
2019-05-01 15:12:44 -04:00
|
|
|
{ "createwallet", 6, "load_on_startup"},
|
2019-08-04 17:56:17 +02:00
|
|
|
{ "createwallet", 7, "external_signer"},
|
2021-07-27 14:28:23 -03:00
|
|
|
{ "restorewallet", 2, "load_on_startup"},
|
2019-05-01 15:12:44 -04:00
|
|
|
{ "loadwallet", 1, "load_on_startup"},
|
|
|
|
{ "unloadwallet", 1, "load_on_startup"},
|
2018-05-02 13:19:40 +01:00
|
|
|
{ "getnodeaddresses", 0, "count"},
|
2020-07-23 18:10:35 +01:00
|
|
|
{ "addpeeraddress", 1, "port"},
|
2021-09-14 12:14:43 +02:00
|
|
|
{ "addpeeraddress", 2, "tried"},
|
2018-11-20 17:52:15 +00:00
|
|
|
{ "stop", 0, "wait" },
|
2014-06-26 22:12:36 -04:00
|
|
|
};
|
2018-08-20 14:19:43 +02:00
|
|
|
// clang-format on
|
2014-06-26 22:12:36 -04:00
|
|
|
|
|
|
|
class CRPCConvertTable
|
|
|
|
{
|
|
|
|
private:
|
2016-11-22 14:56:29 +01:00
|
|
|
std::set<std::pair<std::string, int>> members;
|
|
|
|
std::set<std::pair<std::string, std::string>> membersByName;
|
2014-06-26 22:12:36 -04:00
|
|
|
|
|
|
|
public:
|
|
|
|
CRPCConvertTable();
|
|
|
|
|
|
|
|
bool convert(const std::string& method, int idx) {
|
|
|
|
return (members.count(std::make_pair(method, idx)) > 0);
|
2013-11-20 14:18:57 +01:00
|
|
|
}
|
2016-11-22 14:56:29 +01:00
|
|
|
bool convert(const std::string& method, const std::string& name) {
|
|
|
|
return (membersByName.count(std::make_pair(method, name)) > 0);
|
|
|
|
}
|
2014-06-26 22:12:36 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
CRPCConvertTable::CRPCConvertTable()
|
|
|
|
{
|
2021-01-12 06:27:29 +01:00
|
|
|
for (const auto& cp : vRPCConvertParams) {
|
|
|
|
members.emplace(cp.methodName, cp.paramIdx);
|
|
|
|
membersByName.emplace(cp.methodName, cp.paramName);
|
2013-11-20 14:18:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-26 22:12:36 -04:00
|
|
|
static CRPCConvertTable rpcCvtTable;
|
|
|
|
|
2015-06-04 10:31:22 +02:00
|
|
|
/** 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)
|
2020-06-01 10:35:07 +02:00
|
|
|
throw std::runtime_error(std::string("Error parsing JSON: ") + strVal);
|
2015-06-04 10:31:22 +02:00
|
|
|
return jVal[0];
|
|
|
|
}
|
|
|
|
|
2015-05-13 21:29:19 +02:00
|
|
|
UniValue RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams)
|
2013-11-20 14:18:57 +01:00
|
|
|
{
|
2015-05-10 13:35:44 +02:00
|
|
|
UniValue params(UniValue::VARR);
|
2014-06-26 22:12:36 -04:00
|
|
|
|
|
|
|
for (unsigned int idx = 0; idx < strParams.size(); idx++) {
|
|
|
|
const std::string& strVal = strParams[idx];
|
|
|
|
|
|
|
|
if (!rpcCvtTable.convert(strMethod, idx)) {
|
2015-06-04 10:31:22 +02:00
|
|
|
// insert string value directly
|
2014-06-26 22:12:36 -04:00
|
|
|
params.push_back(strVal);
|
2015-06-04 10:31:22 +02:00
|
|
|
} else {
|
|
|
|
// parse string as JSON, insert bool/number/object/etc. value
|
|
|
|
params.push_back(ParseNonRFCJSONValue(strVal));
|
2014-06-26 22:12:36 -04:00
|
|
|
}
|
|
|
|
}
|
2013-11-20 14:18:57 +01:00
|
|
|
|
|
|
|
return params;
|
|
|
|
}
|
2016-11-22 14:56:29 +01:00
|
|
|
|
|
|
|
UniValue RPCConvertNamedValues(const std::string &strMethod, const std::vector<std::string> &strParams)
|
|
|
|
{
|
|
|
|
UniValue params(UniValue::VOBJ);
|
|
|
|
|
|
|
|
for (const std::string &s: strParams) {
|
2018-01-11 21:40:51 +01:00
|
|
|
size_t pos = s.find('=');
|
2016-11-22 14:56:29 +01:00
|
|
|
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;
|
|
|
|
}
|