Allow disconnectnode() to be called with node id

disconnectnode() can currently only be called with the IP address/port
of the node the user wishes to connect. This commit allows the node to
be disconnected using the nodeid returned by getpeerinfo().
This commit is contained in:
John Newbery 2017-04-03 10:03:00 -04:00
parent 2584925077
commit 23e6e64a24
2 changed files with 28 additions and 7 deletions

View file

@ -115,6 +115,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "bumpfee", 1, "options" },
{ "logging", 0, "include" },
{ "logging", 1, "exclude" },
{ "disconnectnode", 1, "nodeid" },
// Echo with conversion (For testing only)
{ "echojson", 0, "arg0" },
{ "echojson", 1, "arg1" },

View file

@ -234,23 +234,43 @@ UniValue addnode(const JSONRPCRequest& request)
UniValue disconnectnode(const JSONRPCRequest& request)
{
if (request.fHelp || request.params.size() != 1)
if (request.fHelp || request.params.size() == 0 || request.params.size() >= 3)
throw std::runtime_error(
"disconnectnode \"address\" \n"
"\nImmediately disconnects from the specified node.\n"
"disconnectnode \"[address]\" [nodeid]\n"
"\nImmediately disconnects from the specified peer node.\n"
"\nStrictly one out of 'address' and 'nodeid' can be provided to identify the node.\n"
"\nTo disconnect by nodeid, either set 'address' to the empty string, or call using the named 'nodeid' argument only.\n"
"\nArguments:\n"
"1. \"address\" (string, required) The IP address/port of the node\n"
"1. \"address\" (string, optional) The IP address/port of the node\n"
"2. \"nodeid\" (number, optional) The node ID (see getpeerinfo for node IDs)\n"
"\nExamples:\n"
+ HelpExampleCli("disconnectnode", "\"192.168.0.6:8333\"")
+ HelpExampleCli("disconnectnode", "\"\" 1")
+ HelpExampleRpc("disconnectnode", "\"192.168.0.6:8333\"")
+ HelpExampleRpc("disconnectnode", "\"\", 1")
);
if(!g_connman)
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
bool ret = g_connman->DisconnectNode(request.params[0].get_str());
if (!ret)
bool success;
const UniValue &address_arg = request.params[0];
const UniValue &id_arg = request.params.size() < 2 ? NullUniValue : request.params[1];
if (!address_arg.isNull() && id_arg.isNull()) {
/* handle disconnect-by-address */
success = g_connman->DisconnectNode(address_arg.get_str());
} else if (!id_arg.isNull() && (address_arg.isNull() || (address_arg.isStr() && address_arg.get_str().empty()))) {
/* handle disconnect-by-id */
NodeId nodeid = (NodeId) id_arg.get_int64();
success = g_connman->DisconnectNode(nodeid);
} else {
throw JSONRPCError(RPC_INVALID_PARAMS, "Only one of address and nodeid should be provided.");
}
if (!success) {
throw JSONRPCError(RPC_CLIENT_NODE_NOT_CONNECTED, "Node not found in connected nodes");
}
return NullUniValue;
}
@ -607,7 +627,7 @@ static const CRPCCommand commands[] =
{ "network", "ping", &ping, true, {} },
{ "network", "getpeerinfo", &getpeerinfo, true, {} },
{ "network", "addnode", &addnode, true, {"node","command"} },
{ "network", "disconnectnode", &disconnectnode, true, {"address"} },
{ "network", "disconnectnode", &disconnectnode, true, {"address", "nodeid"} },
{ "network", "getaddednodeinfo", &getaddednodeinfo, true, {"node"} },
{ "network", "getnettotals", &getnettotals, true, {} },
{ "network", "getnetworkinfo", &getnetworkinfo, true, {} },