Browse Source

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
0.15
Wladimir J. van der Laan 7 years ago
parent
commit
041dad94b0
No known key found for this signature in database
GPG Key ID: 1E4AED62986CD25D
  1. 22
      src/rpc/blockchain.cpp
  2. 6
      src/rpc/mining.cpp
  3. 2
      src/rpc/net.cpp
  4. 6
      src/rpc/rawtransaction.cpp
  5. 18
      src/wallet/rpcdump.cpp
  6. 48
      src/wallet/rpcwallet.cpp

22
src/rpc/blockchain.cpp

@ -210,7 +210,7 @@ UniValue waitfornewblock(const JSONRPCRequest& request) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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);

6
src/rpc/mining.cpp

@ -102,7 +102,7 @@ UniValue getnetworkhashps(const JSONRPCRequest& request) @@ -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) @@ -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) @@ -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");

2
src/rpc/net.cpp

@ -310,7 +310,7 @@ UniValue getaddednodeinfo(const JSONRPCRequest& request) @@ -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()) {

6
src/rpc/rawtransaction.cpp

@ -137,7 +137,7 @@ UniValue getrawtransaction(const JSONRPCRequest& request) @@ -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) @@ -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) @@ -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");
}

18
src/wallet/rpcdump.cpp

@ -106,12 +106,12 @@ UniValue importprivkey(const JSONRPCRequest& request) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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")) {

48
src/wallet/rpcwallet.cpp

@ -146,7 +146,7 @@ UniValue getnewaddress(const JSONRPCRequest& request) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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 @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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,
{

Loading…
Cancel
Save