Skip to content

Commit

Permalink
Merge bitcoin#11050: Avoid treating null RPC arguments different from…
Browse files Browse the repository at this point in the history
… missing arguments

745d2e3 Clean up getbalance RPC parameter handling (Russell Yanofsky)
fd5d71e Update developer notes after params.size() cleanup (Russell Yanofsky)
e067673 Avoid treating null RPC arguments different from missing arguments (Russell Yanofsky)
e666efc Get rid of redundant RPC params.size() checks (Russell Yanofsky)

Pull request description:

  This is a followup to bitcoin#10783.

  - The first commit doesn't change behavior at all, just simplifies code.
  - The second commit just changes RPC methods to treat null arguments the same as missing arguments instead of throwing type errors.
  - The third commit updates developer notes after the cleanup.
  - The forth commit does some additional code cleanup in `getbalance`.

  Followup changes that should happen in future PRs:

  - [ ] Replace uses of `.isTrue()` with calls to `.get_bool()` so numbers, objects, and strings cause type errors instead of being interpreted as false. bitcoin#11050 (comment)
  - [ ] Add braces around if statements. bitcoin#11050 (comment)
  - [ ] Maybe improve UniValue type error exceptions and eliminate RPCTypeCheck and RPCTypeCheckArgument functions. bitcoin#11050 (comment)

Tree-SHA512: e72f696011d20acc0778e996659e41f9426bffce387b29ff63bf59ad1163d5146761e4445b2b9b9e069a80596a57c7f4402b75a15d5d20f69f775ae558cf67e9
  • Loading branch information
laanwj authored and PastaPastaPasta committed Sep 24, 2019
1 parent cdd561b commit d4aa263
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 62 deletions.
10 changes: 4 additions & 6 deletions doc/developer-notes.md
Expand Up @@ -583,16 +583,14 @@ A few guidelines for introducing and reviewing new RPC interfaces:
is specified as-is in BIP22.

- Missing arguments and 'null' should be treated the same: as default values. If there is no
default value, both cases should fail in the same way.
default value, both cases should fail in the same way. The easiest way to follow this
guideline is detect unspecified arguments with `params[x].isNull()` instead of
`params.size() <= x`. The former returns true if the argument is either null or missing,
while the latter returns true if is missing, and false if it is null.

- *Rationale*: Avoids surprises when switching to name-based arguments. Missing name-based arguments
are passed as 'null'.

- *Exception*: Many legacy exceptions to this exist, one of the worst ones is
`getbalance` which follows a completely different code path based on the
number of arguments. We are still in the process of cleaning these up. Do not introduce
new ones.

- Try not to overload methods on argument type. E.g. don't make `getblock(true)` and `getblock("hash")`
do different things.

Expand Down
4 changes: 2 additions & 2 deletions src/rpc/blockchain.cpp
Expand Up @@ -1786,11 +1786,11 @@ UniValue getchaintxstats(const JSONRPCRequest& request)
const CBlockIndex* pindex;
int blockcount = 30 * 24 * 60 * 60 / Params().GetConsensus().nPowTargetSpacing; // By default: 1 month

if (request.params.size() > 0 && !request.params[0].isNull()) {
if (!request.params[0].isNull()) {
blockcount = request.params[0].get_int();
}

bool havehash = request.params.size() > 1 && !request.params[1].isNull();
bool havehash = !request.params[1].isNull();
uint256 hash;
if (havehash) {
hash = uint256S(request.params[1].get_str());
Expand Down
2 changes: 1 addition & 1 deletion src/rpc/mining.cpp
Expand Up @@ -867,7 +867,7 @@ UniValue estimatesmartfee(const JSONRPCRequest& request)
RPCTypeCheckArgument(request.params[0], UniValue::VNUM);
unsigned int conf_target = ParseConfirmTarget(request.params[0]);
bool conservative = true;
if (request.params.size() > 1 && !request.params[1].isNull()) {
if (!request.params[1].isNull()) {
FeeEstimateMode fee_mode;
if (!FeeModeFromString(request.params[1].get_str(), fee_mode)) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid estimate_mode parameter");
Expand Down
6 changes: 3 additions & 3 deletions src/rpc/misc.cpp
Expand Up @@ -1186,7 +1186,7 @@ UniValue getmemoryinfo(const JSONRPCRequest& request)
+ HelpExampleRpc("getmemoryinfo", "")
);

std::string mode = (request.params.size() < 1 || request.params[0].isNull()) ? "stats" : request.params[0].get_str();
std::string mode = request.params[0].isNull() ? "stats" : request.params[0].get_str();
if (mode == "stats") {
UniValue obj(UniValue::VOBJ);
obj.push_back(Pair("locked", RPCLockedMemoryInfo()));
Expand Down Expand Up @@ -1241,11 +1241,11 @@ UniValue logging(const JSONRPCRequest& request)
}

uint64_t originalLogCategories = logCategories;
if (request.params.size() > 0 && request.params[0].isArray()) {
if (request.params[0].isArray()) {
logCategories |= getCategoryMask(request.params[0]);
}

if (request.params.size() > 1 && request.params[1].isArray()) {
if (request.params[1].isArray()) {
logCategories &= ~getCategoryMask(request.params[1]);
}

Expand Down
12 changes: 6 additions & 6 deletions src/rpc/net.cpp
Expand Up @@ -194,7 +194,7 @@ UniValue getpeerinfo(const JSONRPCRequest& request)
UniValue addnode(const JSONRPCRequest& request)
{
std::string strCommand;
if (request.params.size() == 2)
if (!request.params[1].isNull())
strCommand = request.params[1].get_str();
if (request.fHelp || request.params.size() != 2 ||
(strCommand != "onetry" && strCommand != "add" && strCommand != "remove"))
Expand Down Expand Up @@ -259,7 +259,7 @@ UniValue disconnectnode(const JSONRPCRequest& request)

bool success;
const UniValue &address_arg = request.params[0];
const UniValue &id_arg = request.params.size() < 2 ? NullUniValue : request.params[1];
const UniValue &id_arg = request.params[1];

if (!address_arg.isNull() && id_arg.isNull()) {
/* handle disconnect-by-address */
Expand Down Expand Up @@ -313,7 +313,7 @@ UniValue getaddednodeinfo(const JSONRPCRequest& request)

std::vector<AddedNodeInfo> vInfo = g_connman->GetAddedNodeInfo();

if (request.params.size() == 1 && !request.params[0].isNull()) {
if (!request.params[0].isNull()) {
bool found = false;
for (const AddedNodeInfo& info : vInfo) {
if (info.strAddedNode == request.params[0].get_str()) {
Expand Down Expand Up @@ -492,7 +492,7 @@ UniValue getnetworkinfo(const JSONRPCRequest& request)
UniValue setban(const JSONRPCRequest& request)
{
std::string strCommand;
if (request.params.size() >= 2)
if (!request.params[1].isNull())
strCommand = request.params[1].get_str();
if (request.fHelp || request.params.size() < 2 ||
(strCommand != "add" && strCommand != "remove"))
Expand Down Expand Up @@ -536,11 +536,11 @@ UniValue setban(const JSONRPCRequest& request)
throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: IP/Subnet already banned");

int64_t banTime = 0; //use standard bantime if not specified
if (request.params.size() >= 3 && !request.params[2].isNull())
if (!request.params[2].isNull())
banTime = request.params[2].get_int64();

bool absolute = false;
if (request.params.size() == 4 && request.params[3].isTrue())
if (request.params[3].isTrue())
absolute = true;

isSubnet ? g_connman->Ban(subNet, BanReasonManuallyAdded, banTime, absolute) : g_connman->Ban(netAddr, BanReasonManuallyAdded, banTime, absolute);
Expand Down
10 changes: 5 additions & 5 deletions src/rpc/rawtransaction.cpp
Expand Up @@ -388,7 +388,7 @@ UniValue createrawtransaction(const JSONRPCRequest& request)

CMutableTransaction rawTx;

if (request.params.size() > 2 && !request.params[2].isNull()) {
if (!request.params[2].isNull()) {
int64_t nLockTime = request.params[2].get_int64();
if (nLockTime < 0 || nLockTime > std::numeric_limits<uint32_t>::max())
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, locktime out of range");
Expand Down Expand Up @@ -766,7 +766,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request)

bool fGivenKeys = false;
CBasicKeyStore tempKeystore;
if (request.params.size() > 2 && !request.params[2].isNull()) {
if (!request.params[2].isNull()) {
fGivenKeys = true;
UniValue keys = request.params[2].get_array();
for (unsigned int idx = 0; idx < keys.size(); idx++) {
Expand All @@ -788,7 +788,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request)
#endif

// Add previous txouts given in the RPC call:
if (request.params.size() > 1 && !request.params[1].isNull()) {
if (!request.params[1].isNull()) {
UniValue prevTxs = request.params[1].get_array();
for (unsigned int idx = 0; idx < prevTxs.size(); idx++) {
const UniValue& p = prevTxs[idx];
Expand Down Expand Up @@ -859,7 +859,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request)
#endif

int nHashType = SIGHASH_ALL;
if (request.params.size() > 3 && !request.params[3].isNull()) {
if (!request.params[3].isNull()) {
static std::map<std::string, int> mapSigHashValues = {
{std::string("ALL"), int(SIGHASH_ALL)},
{std::string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY)},
Expand Down Expand Up @@ -955,7 +955,7 @@ UniValue sendrawtransaction(const JSONRPCRequest& request)
const uint256& hashTx = tx->GetHash();

CAmount nMaxRawTxFee = maxTxFee;
if (request.params.size() > 1 && request.params[1].get_bool())
if (!request.params[1].isNull() && request.params[1].get_bool())
nMaxRawTxFee = 0;

bool fBypassLimits = false;
Expand Down

0 comments on commit d4aa263

Please sign in to comment.