Merge #10783: [RPC] Various rpc argument fixes

4dc1915 check for null values in rpc args and handle appropriately (Gregory Sanders)
999ef20 importmulti options are optional (Gregory Sanders)
a70d025 fixup some rpc param counting for rpc help (Gregory Sanders)

Pull request description:

  Audited where named args will fail to use correct default values or may fail when additional optional arguments are added.

  Previously for these parameters, it was fine to omit them as positional arguments, but it would trigger UniValue runtime errors to set them to null, or to omit them while passing named parameters with greater positions (which would internally set earlier missing arguments to null). Now null values are treated the same as missing values so these errors do not occur.

  Included a few other small fixes while working on it.

  I didn't bother fixing account-based rpc calls.

Tree-SHA512: 8baf781a35bd48de7878d4726850a580dab80323d3416c1c146b4fa9062f8a233c03f37e8ae3f3159e9d04a8f39c326627ca64c14e1cb7ce72538f934ab2ae1e
This commit is contained in:
Wladimir J. van der Laan 2017-07-20 17:01:51 +02:00
commit 041dad94b0
No known key found for this signature in database
GPG key ID: 1E4AED62986CD25D
6 changed files with 51 additions and 51 deletions

View file

@ -210,7 +210,7 @@ UniValue waitfornewblock(const JSONRPCRequest& request)
+ HelpExampleRpc("waitfornewblock", "1000")
);
int timeout = 0;
if (request.params.size() > 0)
if (!request.params[0].isNull())
timeout = request.params[0].get_int();
CUpdatedBlock block;
@ -252,7 +252,7 @@ UniValue waitforblock(const JSONRPCRequest& request)
uint256 hash = uint256S(request.params[0].get_str());
if (request.params.size() > 1)
if (!request.params[1].isNull())
timeout = request.params[1].get_int();
CUpdatedBlock block;
@ -295,7 +295,7 @@ UniValue waitforblockheight(const JSONRPCRequest& request)
int height = request.params[0].get_int();
if (request.params.size() > 1)
if (!request.params[1].isNull())
timeout = request.params[1].get_int();
CUpdatedBlock block;
@ -434,7 +434,7 @@ UniValue getrawmempool(const JSONRPCRequest& request)
);
bool fVerbose = false;
if (request.params.size() > 0)
if (!request.params[0].isNull())
fVerbose = request.params[0].get_bool();
return mempoolToJSON(fVerbose);
@ -467,7 +467,7 @@ UniValue getmempoolancestors(const JSONRPCRequest& request)
}
bool fVerbose = false;
if (request.params.size() > 1)
if (!request.params[1].isNull())
fVerbose = request.params[1].get_bool();
uint256 hash = ParseHashV(request.params[0], "parameter 1");
@ -531,7 +531,7 @@ UniValue getmempooldescendants(const JSONRPCRequest& request)
}
bool fVerbose = false;
if (request.params.size() > 1)
if (!request.params[1].isNull())
fVerbose = request.params[1].get_bool();
uint256 hash = ParseHashV(request.params[0], "parameter 1");
@ -666,7 +666,7 @@ UniValue getblockheader(const JSONRPCRequest& request)
uint256 hash(uint256S(strHash));
bool fVerbose = true;
if (request.params.size() > 1)
if (!request.params[1].isNull())
fVerbose = request.params[1].get_bool();
if (mapBlockIndex.count(hash) == 0)
@ -741,7 +741,7 @@ UniValue getblock(const JSONRPCRequest& request)
uint256 hash(uint256S(strHash));
int verbosity = 1;
if (request.params.size() > 1) {
if (!request.params[1].isNull()) {
if(request.params[1].isNum())
verbosity = request.params[1].get_int();
else
@ -984,7 +984,7 @@ UniValue gettxout(const JSONRPCRequest& request)
int n = request.params[1].get_int();
COutPoint out(hash, n);
bool fMempool = true;
if (request.params.size() > 2)
if (!request.params[2].isNull())
fMempool = request.params[2].get_bool();
Coin coin;
@ -1037,9 +1037,9 @@ UniValue verifychain(const JSONRPCRequest& request)
LOCK(cs_main);
if (request.params.size() > 0)
if (!request.params[0].isNull())
nCheckLevel = request.params[0].get_int();
if (request.params.size() > 1)
if (!request.params[1].isNull())
nCheckDepth = request.params[1].get_int();
return CVerifyDB().VerifyDB(Params(), pcoinsTip, nCheckLevel, nCheckDepth);

View file

@ -102,7 +102,7 @@ UniValue getnetworkhashps(const JSONRPCRequest& request)
);
LOCK(cs_main);
return GetNetworkHashPS(request.params.size() > 0 ? request.params[0].get_int() : 120, request.params.size() > 1 ? request.params[1].get_int() : -1);
return GetNetworkHashPS(!request.params[0].isNull() ? request.params[0].get_int() : 120, !request.params[1].isNull() ? request.params[1].get_int() : -1);
}
UniValue generateBlocks(std::shared_ptr<CReserveScript> coinbaseScript, int nGenerate, uint64_t nMaxTries, bool keepScript)
@ -172,7 +172,7 @@ UniValue generatetoaddress(const JSONRPCRequest& request)
int nGenerate = request.params[0].get_int();
uint64_t nMaxTries = 1000000;
if (request.params.size() > 2) {
if (!request.params[2].isNull()) {
nMaxTries = request.params[2].get_int();
}
@ -374,7 +374,7 @@ UniValue getblocktemplate(const JSONRPCRequest& request)
UniValue lpval = NullUniValue;
std::set<std::string> setClientRules;
int64_t nMaxVersionPreVB = -1;
if (request.params.size() > 0)
if (!request.params[0].isNull())
{
const UniValue& oparam = request.params[0].get_obj();
const UniValue& modeval = find_value(oparam, "mode");

View file

@ -310,7 +310,7 @@ UniValue getaddednodeinfo(const JSONRPCRequest& request)
std::vector<AddedNodeInfo> vInfo = g_connman->GetAddedNodeInfo();
if (request.params.size() == 1) {
if (request.params.size() == 1 && !request.params[0].isNull()) {
bool found = false;
for (const AddedNodeInfo& info : vInfo) {
if (info.strAddedNode == request.params[0].get_str()) {

View file

@ -137,7 +137,7 @@ UniValue getrawtransaction(const JSONRPCRequest& request)
// Accept either a bool (true) or a num (>=1) to indicate verbose output.
bool fVerbose = false;
if (request.params.size() > 1) {
if (!request.params[1].isNull()) {
if (request.params[1].isNum()) {
if (request.params[1].get_int() != 0) {
fVerbose = true;
@ -211,7 +211,7 @@ UniValue gettxoutproof(const JSONRPCRequest& request)
CBlockIndex* pblockindex = NULL;
uint256 hashBlock;
if (request.params.size() > 1)
if (!request.params[1].isNull())
{
hashBlock = uint256S(request.params[1].get_str());
if (!mapBlockIndex.count(hashBlock))
@ -412,7 +412,7 @@ UniValue createrawtransaction(const JSONRPCRequest& request)
}
}
if (request.params.size() > 3 && rbfOptIn != SignalsOptInRBF(rawTx)) {
if (!request.params[3].isNull() && rbfOptIn != SignalsOptInRBF(rawTx)) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter combination: Sequence number(s) contradict replaceable option");
}

View file

@ -106,12 +106,12 @@ UniValue importprivkey(const JSONRPCRequest& request)
std::string strSecret = request.params[0].get_str();
std::string strLabel = "";
if (request.params.size() > 1)
if (!request.params[1].isNull())
strLabel = request.params[1].get_str();
// Whether to perform rescan after import
bool fRescan = true;
if (request.params.size() > 2)
if (!request.params[2].isNull())
fRescan = request.params[2].get_bool();
if (fRescan && fPruneMode)
@ -245,12 +245,12 @@ UniValue importaddress(const JSONRPCRequest& request)
std::string strLabel = "";
if (request.params.size() > 1)
if (!request.params[1].isNull())
strLabel = request.params[1].get_str();
// Whether to perform rescan after import
bool fRescan = true;
if (request.params.size() > 2)
if (!request.params[2].isNull())
fRescan = request.params[2].get_bool();
if (fRescan && fPruneMode)
@ -258,7 +258,7 @@ UniValue importaddress(const JSONRPCRequest& request)
// Whether to import a p2sh version, too
bool fP2SH = false;
if (request.params.size() > 3)
if (!request.params[3].isNull())
fP2SH = request.params[3].get_bool();
LOCK2(cs_main, pwallet->cs_wallet);
@ -410,12 +410,12 @@ UniValue importpubkey(const JSONRPCRequest& request)
std::string strLabel = "";
if (request.params.size() > 1)
if (!request.params[1].isNull())
strLabel = request.params[1].get_str();
// Whether to perform rescan after import
bool fRescan = true;
if (request.params.size() > 2)
if (!request.params[2].isNull())
fRescan = request.params[2].get_bool();
if (fRescan && fPruneMode)
@ -1028,7 +1028,7 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
// clang-format off
if (mainRequest.fHelp || mainRequest.params.size() < 1 || mainRequest.params.size() > 2)
throw std::runtime_error(
"importmulti \"requests\" \"options\"\n\n"
"importmulti \"requests\" ( \"options\" )\n\n"
"Import addresses/scripts (with private or public keys, redeem script (P2SH)), rescanning all addresses in one-shot-only (rescan can be disabled via options).\n\n"
"Arguments:\n"
"1. requests (array, required) Data to be imported\n"
@ -1071,7 +1071,7 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
//Default options
bool fRescan = true;
if (mainRequest.params.size() > 1) {
if (!mainRequest.params[1].isNull()) {
const UniValue& options = mainRequest.params[1];
if (options.exists("rescan")) {

View file

@ -146,7 +146,7 @@ UniValue getnewaddress(const JSONRPCRequest& request)
// Parse the account first so we don't generate a key if there's an error
std::string strAccount;
if (request.params.size() > 0)
if (!request.params[0].isNull())
strAccount = AccountFromValue(request.params[0]);
if (!pwallet->IsLocked()) {
@ -217,7 +217,7 @@ UniValue getrawchangeaddress(const JSONRPCRequest& request)
return NullUniValue;
}
if (request.fHelp || request.params.size() > 1)
if (request.fHelp || request.params.size() > 0)
throw std::runtime_error(
"getrawchangeaddress\n"
"\nReturns a new Bitcoin address, for receiving change.\n"
@ -496,7 +496,7 @@ UniValue listaddressgroupings(const JSONRPCRequest& request)
return NullUniValue;
}
if (request.fHelp)
if (request.fHelp || request.params.size() != 0)
throw std::runtime_error(
"listaddressgroupings\n"
"\nLists groups of addresses which have had their common ownership\n"
@ -641,7 +641,7 @@ UniValue getreceivedbyaddress(const JSONRPCRequest& request)
// Minimum confirmations
int nMinDepth = 1;
if (request.params.size() > 1)
if (!request.params[1].isNull())
nMinDepth = request.params[1].get_int();
// Tally
@ -692,7 +692,7 @@ UniValue getreceivedbyaccount(const JSONRPCRequest& request)
// Minimum confirmations
int nMinDepth = 1;
if (request.params.size() > 1)
if (!request.params[1].isNull())
nMinDepth = request.params[1].get_int();
// Get the set of pub keys assigned to account
@ -769,10 +769,10 @@ UniValue getbalance(const JSONRPCRequest& request)
const std::string* account = account_param != "*" ? &account_param : nullptr;
int nMinDepth = 1;
if (request.params.size() > 1)
if (!request.params[1].isNull())
nMinDepth = request.params[1].get_int();
isminefilter filter = ISMINE_SPENDABLE;
if(request.params.size() > 2)
if(!request.params[2].isNull())
if(request.params[2].get_bool())
filter = filter | ISMINE_WATCH_ONLY;
@ -975,7 +975,7 @@ UniValue sendmany(const JSONRPCRequest& request)
std::string strAccount = AccountFromValue(request.params[0]);
UniValue sendTo = request.params[1].get_obj();
int nMinDepth = 1;
if (request.params.size() > 2)
if (!request.params[2].isNull())
nMinDepth = request.params[2].get_int();
CWalletTx wtx;
@ -1222,16 +1222,16 @@ UniValue ListReceived(CWallet * const pwallet, const UniValue& params, bool fByA
{
// Minimum confirmations
int nMinDepth = 1;
if (params.size() > 0)
if (!params[0].isNull())
nMinDepth = params[0].get_int();
// Whether to include empty accounts
bool fIncludeEmpty = false;
if (params.size() > 1)
if (!params[1].isNull())
fIncludeEmpty = params[1].get_bool();
isminefilter filter = ISMINE_SPENDABLE;
if(params.size() > 2)
if(!params[2].isNull())
if(params[2].get_bool())
filter = filter | ISMINE_WATCH_ONLY;
@ -1593,16 +1593,16 @@ UniValue listtransactions(const JSONRPCRequest& request)
LOCK2(cs_main, pwallet->cs_wallet);
std::string strAccount = "*";
if (request.params.size() > 0)
if (!request.params[0].isNull())
strAccount = request.params[0].get_str();
int nCount = 10;
if (request.params.size() > 1)
if (!request.params[1].isNull())
nCount = request.params[1].get_int();
int nFrom = 0;
if (request.params.size() > 2)
if (!request.params[2].isNull())
nFrom = request.params[2].get_int();
isminefilter filter = ISMINE_SPENDABLE;
if(request.params.size() > 3)
if(!request.params[3].isNull())
if(request.params[3].get_bool())
filter = filter | ISMINE_WATCH_ONLY;
@ -1742,7 +1742,7 @@ UniValue listsinceblock(const JSONRPCRequest& request)
return NullUniValue;
}
if (request.fHelp)
if (request.fHelp || request.params.size() > 3)
throw std::runtime_error(
"listsinceblock ( \"blockhash\" target_confirmations include_watchonly)\n"
"\nGet all transactions in blocks since block [blockhash], or all transactions if omitted\n"
@ -1789,7 +1789,7 @@ UniValue listsinceblock(const JSONRPCRequest& request)
int target_confirms = 1;
isminefilter filter = ISMINE_SPENDABLE;
if (request.params.size() > 0)
if (!request.params[0].isNull())
{
uint256 blockId;
@ -1808,7 +1808,7 @@ UniValue listsinceblock(const JSONRPCRequest& request)
}
}
if (request.params.size() > 1)
if (!request.params[1].isNull())
{
target_confirms = request.params[1].get_int();
@ -1900,7 +1900,7 @@ UniValue gettransaction(const JSONRPCRequest& request)
hash.SetHex(request.params[0].get_str());
isminefilter filter = ISMINE_SPENDABLE;
if(request.params.size() > 1)
if(!request.params[1].isNull())
if(request.params[1].get_bool())
filter = filter | ISMINE_WATCH_ONLY;
@ -2022,7 +2022,7 @@ UniValue keypoolrefill(const JSONRPCRequest& request)
// 0 is interpreted by TopUpKeyPool() as the default keypool size given by -keypool
unsigned int kpSize = 0;
if (request.params.size() > 0) {
if (!request.params[0].isNull()) {
if (request.params[0].get_int() < 0)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected valid size.");
kpSize = (unsigned int)request.params[0].get_int();
@ -2615,7 +2615,7 @@ UniValue listunspent(const JSONRPCRequest& request)
CAmount nMinimumSumAmount = MAX_MONEY;
uint64_t nMaximumCount = 0;
if (request.params.size() > 4) {
if (!request.params[4].isNull()) {
const UniValue& options = request.params[4].get_obj();
if (options.exists("minimumAmount"))
@ -2684,7 +2684,7 @@ UniValue fundrawtransaction(const JSONRPCRequest& request)
return NullUniValue;
}
if (request.fHelp || request.params.size() < 1 || request.params.size() > 3)
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
throw std::runtime_error(
"fundrawtransaction \"hexstring\" ( options )\n"
"\nAdd inputs to a transaction until it has enough in value to meet its out value.\n"
@ -2746,7 +2746,7 @@ UniValue fundrawtransaction(const JSONRPCRequest& request)
UniValue subtractFeeFromOutputs;
std::set<int> setSubtractFeeFromOutputs;
if (request.params.size() > 1) {
if (!request.params[1].isNull()) {
if (request.params[1].type() == UniValue::VBOOL) {
// backward compatibility bool only fallback
coinControl.fAllowWatchOnly = request.params[1].get_bool();
@ -2911,7 +2911,7 @@ UniValue bumpfee(const JSONRPCRequest& request)
CAmount totalFee = 0;
CCoinControl coin_control;
coin_control.signalRbf = true;
if (request.params.size() > 1) {
if (!request.params[1].isNull()) {
UniValue options = request.params[1];
RPCTypeCheckObj(options,
{