[RPC] Various rpc argument fixes #10783

Merged
merged 3 commits into from Jul 20, 2017

Conversation

Projects
None yet
7 participants
Member

instagibbs commented Jul 10, 2017 edited

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.

instagibbs referenced this pull request in ElementsProject/elements Jul 10, 2017

Open

[WIP] sendtoaddress named arguments work with asset args #204

@ryanofsky

utACK 0ff520d. This is a nice PR, and gets rid of most of the cases where null arguments are treated differently than missing arguments. There are few cases not handled here (getbalance, lockunspent) that are handled in master...ryanofsky:pr/multiopt, but these could be taken care of in a followup.

Note that if we wanted to, we could easily enforce that missing arguments are treated the same as null arguments by making a change like 3fc286b.

src/rpc/blockchain.cpp
@@ -210,7 +210,7 @@ UniValue waitfornewblock(const JSONRPCRequest& request)
+ HelpExampleRpc("waitfornewblock", "1000")
);
int timeout = 0;
- if (request.params.size() > 0)
+ if (request.params.size() > 0 && !request.params[0].isNull())
@ryanofsky

ryanofsky Jul 10, 2017

Contributor

In commit "check for null values in rpc args and handle appropriately"

Instead of writing request.params.size() > X && !request.params[X].isNull() everywhere, I think you should just prefer !request.params[X].isNull(). The UniValue array implementation has bounds checking built in and already returns null for missing elements.

laanwj added the RPC/REST/ZMQ label Jul 11, 2017

Contributor

promag commented Jul 11, 2017

Needs rebase, #10589 added more RPC arguments.

Member

instagibbs commented Jul 11, 2017

@ryanofsky since things are moving underneath me I'll leave the code simplification for a follow-up PR

now covering the getbalance and lockunspent cases

@ryanofsky

Conditional utACK 03de1b6 if the getbalance and lockunspent changes are reverted.

@ryanofsky since things are moving underneath me I'll leave the code simplification for a follow-up PR

I don't see a reason to go through this whole process again in another PR. You can simplify your PR right now by running:

git checkout rpcargfixes # (assuming 03de1b66d560164187120711468e1e84c197df37)
git log -p -n1 | git apply -R
git log -p -n1 | sed '/+/s/request.params.size() > \([0-9]\) && \(!request.params\[\1\]\)/\2/' | git apply
git commit -a --amend --no-edit
git push -f
src/wallet/rpcwallet.cpp
@@ -753,14 +753,14 @@ UniValue getbalance(const JSONRPCRequest& request)
if (request.params.size() == 0)
return ValueFromAmount(pwallet->GetBalance());
- const std::string& account_param = request.params[0].get_str();
+ const std::string& account_param = !request.params[0].isNull() ? request.params[0].get_str() : "";
@ryanofsky

ryanofsky Jul 11, 2017

Contributor

Please revert this line. This is treating a null account the same as the default account ("") instead of treating a null account the same as an unspecified account (params.size() == 0), which you would need to do by changing the params.size() check above (like I did in master...ryanofsky:pr/multiopt and verified with 3fc286b).

src/wallet/rpcwallet.cpp
@@ -2309,7 +2309,7 @@ UniValue lockunspent(const JSONRPCRequest& request)
return true;
}
- UniValue outputs = request.params[1].get_array();
+ UniValue outputs = !request.params[1].isNull() ? request.params[1].get_array() : NullUniValue;
@ryanofsky

ryanofsky Jul 11, 2017

Contributor

Should revert this line too. This is pointless because of the type check above.

I think it's best to stick to just handling the simple cases of missing values being treated differently from null values in this PR and handle the other cases more thoughtfully in another PR. Again, I already have the changes to do this in my multiopt branch, and would be happy to post a followup that builds on your change.

Member

instagibbs commented Jul 11, 2017

reverted two changes as suggested and simplified PR(need to improve my sed foo)

@ryanofsky

utACK 1ab6cc0 if the bug in ListReceived (see below) is fixed. Change looks good and gets rid of most of the cases where code treats null arguments different from missing arguments.

src/wallet/rpcwallet.cpp
@@ -1209,16 +1209,16 @@ UniValue ListReceived(CWallet * const pwallet, const UniValue& params, bool fByA
{
// Minimum confirmations
int nMinDepth = 1;
- if (params.size() > 0)
+ if (params[0].isNull())
@ryanofsky

ryanofsky Jul 11, 2017

Contributor

Missing ! here

Contributor

TheBlueMatt commented Jul 11, 2017

utACK 534963d

@ryanofsky

utACK 534963d. Unchanged except bugfix in ListReceived.

Contributor

ryanofsky commented Jul 17, 2017

Needs rebase. Would be nice to have more review, too because (as mentioned) I'd like to do some more cleanup on top of this.

Member

instagibbs commented Jul 17, 2017

rebased

@promag

Minor nits, otherwise utACK.

@@ -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()) {
@promag

promag Jul 17, 2017

Contributor

Remove request.params.size() == 1 &&?

@@ -101,7 +101,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);
@promag

promag Jul 17, 2017

Contributor

Avoid negation?

return GetNetworkHashPS(request.params[0].isNull() ? 120 : request.params[0].get_int(), request.params[1].isNull() ? -1 : request.params[1].get_int());
@ryanofsky

utACK 4dc1915. No changes since previous other than rebase to avoid conflict with recent fee estimation change on adjacent line.

Might be good to clarify PR description to say how this change affects behavior. 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.

@@ -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()) {
@promag

promag Jul 18, 2017

Contributor

This could be simplified to:

bool fVerbose = false;
if (request.params[1].isNum()) {
    fVerbose = request.params[1].get_int() != 0;
} else if (!request.params[1].isNull()) {
    fVerbose = request.params[1].get_bool();
}

With the advantage of removing custom error handling.

Owner

sipa commented Jul 19, 2017

utACK 4dc1915. @promag has a number of useful suggestions that could be included.

Owner

sipa commented Jul 19, 2017

I would like to see this in 0.15 still - it's effectively (at least partially) fixing the incomplete support for named arguments introduced in the previous version.

Member

instagibbs commented Jul 19, 2017

for the purpose of getting this merged as a 0.15 bugfix I'm going to avoid invalidating review for nits (unless told otherwise)

Owner

laanwj commented Jul 19, 2017

utACK 4dc1915, I didn't know univalue returned NullUniValue for out-of-bounds accesses, I always wrote bound checks, but this is better.

laanwj added this to the 0.15.0 milestone Jul 19, 2017

@laanwj laanwj merged commit 4dc1915 into bitcoin:master Jul 20, 2017

1 check passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details

@laanwj laanwj added a commit that referenced this pull request Jul 20, 2017

@laanwj laanwj 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
041dad9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment