Skip to content
This repository has been archived by the owner on Dec 15, 2022. It is now read-only.

Commit

Permalink
Merge bitcoin#8811: rpc: Add support for JSON-RPC named arguments
Browse files Browse the repository at this point in the history
4e7e2e1 Update RPC argument names (John Newbery)
481f289 rpc: Named argument support for bitcoin-cli (Wladimir J. van der Laan)
9adb4e1 rpc: Argument name consistency (Wladimir J. van der Laan)
8d713f7 rpc: Named arguments for rawtransaction calls (Wladimir J. van der Laan)
37a166f rpc: Named arguments for wallet calls (Wladimir J. van der Laan)
78b684f rpc: Named arguments for mining calls (Wladimir J. van der Laan)
b8ebc59 rpc: Named arguments for net calls (Wladimir J. van der Laan)
2ca9dcd test: Add test for RPC named arguments (Wladimir J. van der Laan)
fba1a61 rpc: Named arguments for misc calls (Wladimir J. van der Laan)
286ec08 rpc: Add 'echo' call for testing (Wladimir J. van der Laan)
495eb44 rpc: Named arguments for blockchain calls (Wladimir J. van der Laan)
6f1c76a rpc: Support named arguments (Wladimir J. van der Laan)
5865d41 authproxy: Add support for RPC named arguments (Wladimir J. van der Laan)
  • Loading branch information
laanwj committed Jan 10, 2017
2 parents 68eb562 + 4e7e2e1 commit 5754e03
Show file tree
Hide file tree
Showing 16 changed files with 540 additions and 348 deletions.
1 change: 1 addition & 0 deletions qa/pull-tester/rpc-tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@
'signmessages.py',
'nulldummy.py',
'import-rescan.py',
'rpcnamedargs.py',
]
if ENABLE_ZMQ:
testScripts.append('zmq_test.py')
Expand Down
52 changes: 52 additions & 0 deletions qa/rpc-tests/rpcnamedargs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/usr/bin/env python3
# Copyright (c) 2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

from decimal import Decimal

from test_framework.test_framework import BitcoinTestFramework
from test_framework.authproxy import JSONRPCException
from test_framework.util import (
assert_equal,
assert_raises_jsonrpc,
assert_is_hex_string,
assert_is_hash_string,
start_nodes,
connect_nodes_bi,
)


class NamedArgumentTest(BitcoinTestFramework):
"""
Test named arguments on RPC calls.
"""

def __init__(self):
super().__init__()
self.setup_clean_chain = False
self.num_nodes = 1

def setup_network(self, split=False):
self.nodes = start_nodes(self.num_nodes, self.options.tmpdir)
self.is_network_split = False
self.sync_all()

def run_test(self):
node = self.nodes[0]
h = node.help(command='getinfo')
assert(h.startswith('getinfo\n'))

assert_raises_jsonrpc(-8, node.help, random='getinfo')

h = node.getblockhash(height=0)
node.getblock(blockhash=h)

assert_equal(node.echo(), [])
assert_equal(node.echo(arg0=0,arg9=9), [0] + [None]*8 + [9])
assert_equal(node.echo(arg1=1), [None, 1])
assert_equal(node.echo(arg9=None), [None]*10)
assert_equal(node.echo(arg0=0,arg3=3,arg9=9), [0] + [None]*2 + [3] + [None]*5 + [9])

if __name__ == '__main__':
NamedArgumentTest().main()
6 changes: 4 additions & 2 deletions qa/rpc-tests/test_framework/authproxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,14 +138,16 @@ def _request(self, method, path, postdata):
self.__conn.request(method, path, postdata, headers)
return self._get_response()

def __call__(self, *args):
def __call__(self, *args, **argsn):
AuthServiceProxy.__id_count += 1

log.debug("-%s-> %s %s"%(AuthServiceProxy.__id_count, self._service_name,
json.dumps(args, default=EncodeDecimal, ensure_ascii=self.ensure_ascii)))
if args and argsn:
raise ValueError('Cannot handle both named and positional arguments')
postdata = json.dumps({'version': '1.1',
'method': self._service_name,
'params': args,
'params': args or argsn,
'id': AuthServiceProxy.__id_count}, default=EncodeDecimal, ensure_ascii=self.ensure_ascii)
response = self._request('POST', self.__url.path, postdata.encode('utf-8'))
if response['error'] is not None:
Expand Down
12 changes: 12 additions & 0 deletions qa/rpc-tests/test_framework/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,18 @@ def assert_raises_message(exc, message, fun, *args, **kwds):
else:
raise AssertionError("No exception raised")

def assert_raises_jsonrpc(code, fun, *args, **kwds):
'''Check for specific JSONRPC exception code'''
try:
fun(*args, **kwds)
except JSONRPCException as e:
if e.error["code"] != code:
raise AssertionError("Unexpected JSONRPC error code %i" % e.error["code"])
except Exception as e:
raise AssertionError("Unexpected exception raised: "+type(e).__name__)
else:
raise AssertionError("No exception raised")

def assert_is_hex_string(string):
try:
int(string, 16)
Expand Down
12 changes: 11 additions & 1 deletion src/bitcoin-cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

static const char DEFAULT_RPCCONNECT[] = "127.0.0.1";
static const int DEFAULT_HTTP_CLIENT_TIMEOUT=900;
static const bool DEFAULT_NAMED=false;
static const int CONTINUE_EXECUTION=-1;

std::string HelpMessageCli()
Expand All @@ -35,6 +36,7 @@ std::string HelpMessageCli()
strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), BITCOIN_CONF_FILENAME));
strUsage += HelpMessageOpt("-datadir=<dir>", _("Specify data directory"));
AppendParamsHelpMessages(strUsage);
strUsage += HelpMessageOpt("-named", strprintf(_("Pass named instead of positional arguments (default: %s)"), DEFAULT_NAMED));
strUsage += HelpMessageOpt("-rpcconnect=<ip>", strprintf(_("Send commands to node running on <ip> (default: %s)"), DEFAULT_RPCCONNECT));
strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Connect to JSON-RPC on <port> (default: %u or testnet: %u)"), BaseParams(CBaseChainParams::MAIN).RPCPort(), BaseParams(CBaseChainParams::TESTNET).RPCPort()));
strUsage += HelpMessageOpt("-rpcwait", _("Wait for RPC server to start"));
Expand Down Expand Up @@ -80,6 +82,7 @@ static int AppInitRPC(int argc, char* argv[])
if (!IsArgSet("-version")) {
strUsage += "\n" + _("Usage:") + "\n" +
" bitcoin-cli [options] <command> [params] " + strprintf(_("Send command to %s"), _(PACKAGE_NAME)) + "\n" +
" bitcoin-cli [options] -named <command> [name=value] ... " + strprintf(_("Send command to %s (with named arguments)"), _(PACKAGE_NAME)) + "\n" +
" bitcoin-cli [options] help " + _("List commands") + "\n" +
" bitcoin-cli [options] help <command> " + _("Get help for a command") + "\n";

Expand Down Expand Up @@ -278,7 +281,14 @@ int CommandLineRPC(int argc, char *argv[])
if (args.size() < 1)
throw std::runtime_error("too few parameters (need at least command)");
std::string strMethod = args[0];
UniValue params = RPCConvertValues(strMethod, std::vector<std::string>(args.begin()+1, args.end()));
args.erase(args.begin()); // Remove trailing method name from arguments vector

UniValue params;
if(GetBoolArg("-named", DEFAULT_NAMED)) {
params = RPCConvertNamedValues(strMethod, args);
} else {
params = RPCConvertValues(strMethod, args);
}

// Execute and handle connection failures with -rpcwait
const bool fWait = GetBoolArg("-rpcwait", false);
Expand Down
Loading

0 comments on commit 5754e03

Please sign in to comment.