From 23e6e64a247ef61388f9b8902bc448f0c6159e0e Mon Sep 17 00:00:00 2001 From: John Newbery Date: Mon, 3 Apr 2017 10:03:00 -0400 Subject: 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(). --- src/rpc/client.cpp | 1 + src/rpc/net.cpp | 34 +++++++++++++++++++++++++++------- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 1f3c4e52ad..941bdd9379 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -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" }, diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index e4a909c1f6..cde5ae723b 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -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, {} }, -- cgit v1.2.3 From d6564a26f4afc28d7d1a24b94946916387c9bf24 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Wed, 19 Apr 2017 11:07:44 -0400 Subject: [tests] fix nodehandling.py flake8 warnings --- test/functional/nodehandling.py | 46 +++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/test/functional/nodehandling.py b/test/functional/nodehandling.py index a6b10a0d83..2124069d0f 100755 --- a/test/functional/nodehandling.py +++ b/test/functional/nodehandling.py @@ -3,13 +3,19 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test node handling.""" +import time +import urllib.parse from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * - -import urllib.parse +from test_framework.util import (assert_equal, + assert_raises_jsonrpc, + connect_nodes_bi, + p2p_port, + start_node, + stop_node, + ) -class NodeHandlingTest (BitcoinTestFramework): +class NodeHandlingTest(BitcoinTestFramework): def __init__(self): super().__init__() @@ -20,10 +26,10 @@ class NodeHandlingTest (BitcoinTestFramework): ########################### # setban/listbanned tests # ########################### - assert_equal(len(self.nodes[2].getpeerinfo()), 4) #we should have 4 nodes at this point + assert_equal(len(self.nodes[2].getpeerinfo()), 4) # we should have 4 nodes at this point self.nodes[2].setban("127.0.0.1", "add") - time.sleep(3) #wait till the nodes are disconected - assert_equal(len(self.nodes[2].getpeerinfo()), 0) #all nodes must be disconnected at this point + time.sleep(3) # wait till the nodes are disconected + assert_equal(len(self.nodes[2].getpeerinfo()), 0) # all nodes must be disconnected at this point assert_equal(len(self.nodes[2].listbanned()), 1) self.nodes[2].clearbanned() assert_equal(len(self.nodes[2].listbanned()), 0) @@ -33,7 +39,7 @@ class NodeHandlingTest (BitcoinTestFramework): assert_raises_jsonrpc(-23, "IP/Subnet already banned", self.nodes[2].setban, "127.0.0.1", "add") # This will throw an exception because 127.0.0.1/42 is not a real subnet assert_raises_jsonrpc(-30, "Error: Invalid IP/Subnet", self.nodes[2].setban, "127.0.0.1/42", "add") - assert_equal(len(self.nodes[2].listbanned()), 1) #still only one banned ip because 127.0.0.1 is within the range of 127.0.0.0/24 + assert_equal(len(self.nodes[2].listbanned()), 1) # still only one banned ip because 127.0.0.1 is within the range of 127.0.0.0/24 # This will throw an exception because 127.0.0.1 was not added above assert_raises_jsonrpc(-30, "Error: Unban failed", self.nodes[2].setban, "127.0.0.1", "remove") assert_equal(len(self.nodes[2].listbanned()), 1) @@ -42,16 +48,16 @@ class NodeHandlingTest (BitcoinTestFramework): self.nodes[2].clearbanned() assert_equal(len(self.nodes[2].listbanned()), 0) - ##test persisted banlist + # test persisted banlist self.nodes[2].setban("127.0.0.0/32", "add") self.nodes[2].setban("127.0.0.0/24", "add") - self.nodes[2].setban("192.168.0.1", "add", 1) #ban for 1 seconds - self.nodes[2].setban("2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/19", "add", 1000) #ban for 1000 seconds + self.nodes[2].setban("192.168.0.1", "add", 1) # ban for 1 seconds + self.nodes[2].setban("2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/19", "add", 1000) # ban for 1000 seconds listBeforeShutdown = self.nodes[2].listbanned() - assert_equal("192.168.0.1/32", listBeforeShutdown[2]['address']) #must be here - time.sleep(2) #make 100% sure we expired 192.168.0.1 node time + assert_equal("192.168.0.1/32", listBeforeShutdown[2]['address']) # must be here + time.sleep(2) # make 100% sure we expired 192.168.0.1 node time - #stop node + # stop node stop_node(self.nodes[2], 2) self.nodes[2] = start_node(2, self.options.tmpdir) @@ -64,17 +70,17 @@ class NodeHandlingTest (BitcoinTestFramework): # RPC disconnectnode test # ########################### url = urllib.parse.urlparse(self.nodes[1].url) - self.nodes[0].disconnectnode(url.hostname+":"+str(p2p_port(1))) - time.sleep(2) #disconnecting a node needs a little bit of time + self.nodes[0].disconnectnode(url.hostname + ":" + str(p2p_port(1))) + time.sleep(2) # disconnecting a node needs a little bit of time for node in self.nodes[0].getpeerinfo(): - assert(node['addr'] != url.hostname+":"+str(p2p_port(1))) + assert(node['addr'] != url.hostname + ":" + str(p2p_port(1))) - connect_nodes_bi(self.nodes,0,1) #reconnect the node + connect_nodes_bi(self.nodes, 0, 1) # reconnect the node found = False for node in self.nodes[0].getpeerinfo(): - if node['addr'] == url.hostname+":"+str(p2p_port(1)): + if node['addr'] == url.hostname + ":" + str(p2p_port(1)): found = True assert(found) if __name__ == '__main__': - NodeHandlingTest ().main () + NodeHandlingTest().main() -- cgit v1.2.3 From e367ad5b441d44479d40d6b04a270a571d073a65 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Wed, 19 Apr 2017 11:14:53 -0400 Subject: [tests] rename nodehandling to disconnectban --- test/functional/disconnect_ban.py | 86 +++++++++++++++++++++++++++++++++++++++ test/functional/nodehandling.py | 86 --------------------------------------- test/functional/test_runner.py | 2 +- 3 files changed, 87 insertions(+), 87 deletions(-) create mode 100755 test/functional/disconnect_ban.py delete mode 100755 test/functional/nodehandling.py diff --git a/test/functional/disconnect_ban.py b/test/functional/disconnect_ban.py new file mode 100755 index 0000000000..458b66af03 --- /dev/null +++ b/test/functional/disconnect_ban.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-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. +"""Test node disconnect and ban behavior""" +import time +import urllib.parse + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import (assert_equal, + assert_raises_jsonrpc, + connect_nodes_bi, + p2p_port, + start_node, + stop_node, + ) + +class DisconnectBanTest(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.num_nodes = 4 + self.setup_clean_chain = False + + def run_test(self): + ########################### + # setban/listbanned tests # + ########################### + assert_equal(len(self.nodes[2].getpeerinfo()), 4) # we should have 4 nodes at this point + self.nodes[2].setban("127.0.0.1", "add") + time.sleep(3) # wait till the nodes are disconected + assert_equal(len(self.nodes[2].getpeerinfo()), 0) # all nodes must be disconnected at this point + assert_equal(len(self.nodes[2].listbanned()), 1) + self.nodes[2].clearbanned() + assert_equal(len(self.nodes[2].listbanned()), 0) + self.nodes[2].setban("127.0.0.0/24", "add") + assert_equal(len(self.nodes[2].listbanned()), 1) + # This will throw an exception because 127.0.0.1 is within range 127.0.0.0/24 + assert_raises_jsonrpc(-23, "IP/Subnet already banned", self.nodes[2].setban, "127.0.0.1", "add") + # This will throw an exception because 127.0.0.1/42 is not a real subnet + assert_raises_jsonrpc(-30, "Error: Invalid IP/Subnet", self.nodes[2].setban, "127.0.0.1/42", "add") + assert_equal(len(self.nodes[2].listbanned()), 1) # still only one banned ip because 127.0.0.1 is within the range of 127.0.0.0/24 + # This will throw an exception because 127.0.0.1 was not added above + assert_raises_jsonrpc(-30, "Error: Unban failed", self.nodes[2].setban, "127.0.0.1", "remove") + assert_equal(len(self.nodes[2].listbanned()), 1) + self.nodes[2].setban("127.0.0.0/24", "remove") + assert_equal(len(self.nodes[2].listbanned()), 0) + self.nodes[2].clearbanned() + assert_equal(len(self.nodes[2].listbanned()), 0) + + # test persisted banlist + self.nodes[2].setban("127.0.0.0/32", "add") + self.nodes[2].setban("127.0.0.0/24", "add") + self.nodes[2].setban("192.168.0.1", "add", 1) # ban for 1 seconds + self.nodes[2].setban("2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/19", "add", 1000) # ban for 1000 seconds + listBeforeShutdown = self.nodes[2].listbanned() + assert_equal("192.168.0.1/32", listBeforeShutdown[2]['address']) # must be here + time.sleep(2) # make 100% sure we expired 192.168.0.1 node time + + # stop node + stop_node(self.nodes[2], 2) + + self.nodes[2] = start_node(2, self.options.tmpdir) + listAfterShutdown = self.nodes[2].listbanned() + assert_equal("127.0.0.0/24", listAfterShutdown[0]['address']) + assert_equal("127.0.0.0/32", listAfterShutdown[1]['address']) + assert_equal("/19" in listAfterShutdown[2]['address'], True) + + ########################### + # RPC disconnectnode test # + ########################### + url = urllib.parse.urlparse(self.nodes[1].url) + self.nodes[0].disconnectnode(url.hostname + ":" + str(p2p_port(1))) + time.sleep(2) # disconnecting a node needs a little bit of time + for node in self.nodes[0].getpeerinfo(): + assert(node['addr'] != url.hostname + ":" + str(p2p_port(1))) + + connect_nodes_bi(self.nodes, 0, 1) # reconnect the node + found = False + for node in self.nodes[0].getpeerinfo(): + if node['addr'] == url.hostname + ":" + str(p2p_port(1)): + found = True + assert(found) + +if __name__ == '__main__': + DisconnectBanTest().main() diff --git a/test/functional/nodehandling.py b/test/functional/nodehandling.py deleted file mode 100755 index 2124069d0f..0000000000 --- a/test/functional/nodehandling.py +++ /dev/null @@ -1,86 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2014-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. -"""Test node handling.""" -import time -import urllib.parse - -from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import (assert_equal, - assert_raises_jsonrpc, - connect_nodes_bi, - p2p_port, - start_node, - stop_node, - ) - -class NodeHandlingTest(BitcoinTestFramework): - - def __init__(self): - super().__init__() - self.num_nodes = 4 - self.setup_clean_chain = False - - def run_test(self): - ########################### - # setban/listbanned tests # - ########################### - assert_equal(len(self.nodes[2].getpeerinfo()), 4) # we should have 4 nodes at this point - self.nodes[2].setban("127.0.0.1", "add") - time.sleep(3) # wait till the nodes are disconected - assert_equal(len(self.nodes[2].getpeerinfo()), 0) # all nodes must be disconnected at this point - assert_equal(len(self.nodes[2].listbanned()), 1) - self.nodes[2].clearbanned() - assert_equal(len(self.nodes[2].listbanned()), 0) - self.nodes[2].setban("127.0.0.0/24", "add") - assert_equal(len(self.nodes[2].listbanned()), 1) - # This will throw an exception because 127.0.0.1 is within range 127.0.0.0/24 - assert_raises_jsonrpc(-23, "IP/Subnet already banned", self.nodes[2].setban, "127.0.0.1", "add") - # This will throw an exception because 127.0.0.1/42 is not a real subnet - assert_raises_jsonrpc(-30, "Error: Invalid IP/Subnet", self.nodes[2].setban, "127.0.0.1/42", "add") - assert_equal(len(self.nodes[2].listbanned()), 1) # still only one banned ip because 127.0.0.1 is within the range of 127.0.0.0/24 - # This will throw an exception because 127.0.0.1 was not added above - assert_raises_jsonrpc(-30, "Error: Unban failed", self.nodes[2].setban, "127.0.0.1", "remove") - assert_equal(len(self.nodes[2].listbanned()), 1) - self.nodes[2].setban("127.0.0.0/24", "remove") - assert_equal(len(self.nodes[2].listbanned()), 0) - self.nodes[2].clearbanned() - assert_equal(len(self.nodes[2].listbanned()), 0) - - # test persisted banlist - self.nodes[2].setban("127.0.0.0/32", "add") - self.nodes[2].setban("127.0.0.0/24", "add") - self.nodes[2].setban("192.168.0.1", "add", 1) # ban for 1 seconds - self.nodes[2].setban("2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/19", "add", 1000) # ban for 1000 seconds - listBeforeShutdown = self.nodes[2].listbanned() - assert_equal("192.168.0.1/32", listBeforeShutdown[2]['address']) # must be here - time.sleep(2) # make 100% sure we expired 192.168.0.1 node time - - # stop node - stop_node(self.nodes[2], 2) - - self.nodes[2] = start_node(2, self.options.tmpdir) - listAfterShutdown = self.nodes[2].listbanned() - assert_equal("127.0.0.0/24", listAfterShutdown[0]['address']) - assert_equal("127.0.0.0/32", listAfterShutdown[1]['address']) - assert_equal("/19" in listAfterShutdown[2]['address'], True) - - ########################### - # RPC disconnectnode test # - ########################### - url = urllib.parse.urlparse(self.nodes[1].url) - self.nodes[0].disconnectnode(url.hostname + ":" + str(p2p_port(1))) - time.sleep(2) # disconnecting a node needs a little bit of time - for node in self.nodes[0].getpeerinfo(): - assert(node['addr'] != url.hostname + ":" + str(p2p_port(1))) - - connect_nodes_bi(self.nodes, 0, 1) # reconnect the node - found = False - for node in self.nodes[0].getpeerinfo(): - if node['addr'] == url.hostname + ":" + str(p2p_port(1)): - found = True - assert(found) - -if __name__ == '__main__': - NodeHandlingTest().main() diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index bb12328ec1..0868700387 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -80,7 +80,7 @@ BASE_SCRIPTS= [ 'multi_rpc.py', 'proxy_test.py', 'signrawtransactions.py', - 'nodehandling.py', + 'disconnect_ban.py', 'decodescript.py', 'blockchain.py', 'disablewallet.py', -- cgit v1.2.3 From 395561becfa612fedec74fd841cb4f28afdc23d7 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Wed, 19 Apr 2017 11:25:31 -0400 Subject: [tests] disconnectban test - only use two nodes --- test/functional/disconnect_ban.py | 60 ++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/test/functional/disconnect_ban.py b/test/functional/disconnect_ban.py index 458b66af03..cb4efc8f45 100755 --- a/test/functional/disconnect_ban.py +++ b/test/functional/disconnect_ban.py @@ -19,53 +19,61 @@ class DisconnectBanTest(BitcoinTestFramework): def __init__(self): super().__init__() - self.num_nodes = 4 + self.num_nodes = 2 self.setup_clean_chain = False + def setup_network(self): + self.nodes = self.setup_nodes() + connect_nodes_bi(self.nodes, 0, 1) + def run_test(self): ########################### # setban/listbanned tests # ########################### - assert_equal(len(self.nodes[2].getpeerinfo()), 4) # we should have 4 nodes at this point - self.nodes[2].setban("127.0.0.1", "add") + assert_equal(len(self.nodes[1].getpeerinfo()), 2) # node1 should have 2 connections to node0 at this point + self.nodes[1].setban("127.0.0.1", "add") time.sleep(3) # wait till the nodes are disconected - assert_equal(len(self.nodes[2].getpeerinfo()), 0) # all nodes must be disconnected at this point - assert_equal(len(self.nodes[2].listbanned()), 1) - self.nodes[2].clearbanned() - assert_equal(len(self.nodes[2].listbanned()), 0) - self.nodes[2].setban("127.0.0.0/24", "add") - assert_equal(len(self.nodes[2].listbanned()), 1) + assert_equal(len(self.nodes[1].getpeerinfo()), 0) # all nodes must be disconnected at this point + assert_equal(len(self.nodes[1].listbanned()), 1) + self.nodes[1].clearbanned() + assert_equal(len(self.nodes[1].listbanned()), 0) + self.nodes[1].setban("127.0.0.0/24", "add") + assert_equal(len(self.nodes[1].listbanned()), 1) # This will throw an exception because 127.0.0.1 is within range 127.0.0.0/24 - assert_raises_jsonrpc(-23, "IP/Subnet already banned", self.nodes[2].setban, "127.0.0.1", "add") + assert_raises_jsonrpc(-23, "IP/Subnet already banned", self.nodes[1].setban, "127.0.0.1", "add") # This will throw an exception because 127.0.0.1/42 is not a real subnet - assert_raises_jsonrpc(-30, "Error: Invalid IP/Subnet", self.nodes[2].setban, "127.0.0.1/42", "add") - assert_equal(len(self.nodes[2].listbanned()), 1) # still only one banned ip because 127.0.0.1 is within the range of 127.0.0.0/24 + assert_raises_jsonrpc(-30, "Error: Invalid IP/Subnet", self.nodes[1].setban, "127.0.0.1/42", "add") + assert_equal(len(self.nodes[1].listbanned()), 1) # still only one banned ip because 127.0.0.1 is within the range of 127.0.0.0/24 # This will throw an exception because 127.0.0.1 was not added above - assert_raises_jsonrpc(-30, "Error: Unban failed", self.nodes[2].setban, "127.0.0.1", "remove") - assert_equal(len(self.nodes[2].listbanned()), 1) - self.nodes[2].setban("127.0.0.0/24", "remove") - assert_equal(len(self.nodes[2].listbanned()), 0) - self.nodes[2].clearbanned() - assert_equal(len(self.nodes[2].listbanned()), 0) + assert_raises_jsonrpc(-30, "Error: Unban failed", self.nodes[1].setban, "127.0.0.1", "remove") + assert_equal(len(self.nodes[1].listbanned()), 1) + self.nodes[1].setban("127.0.0.0/24", "remove") + assert_equal(len(self.nodes[1].listbanned()), 0) + self.nodes[1].clearbanned() + assert_equal(len(self.nodes[1].listbanned()), 0) # test persisted banlist - self.nodes[2].setban("127.0.0.0/32", "add") - self.nodes[2].setban("127.0.0.0/24", "add") - self.nodes[2].setban("192.168.0.1", "add", 1) # ban for 1 seconds - self.nodes[2].setban("2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/19", "add", 1000) # ban for 1000 seconds - listBeforeShutdown = self.nodes[2].listbanned() + self.nodes[1].setban("127.0.0.0/32", "add") + self.nodes[1].setban("127.0.0.0/24", "add") + self.nodes[1].setban("192.168.0.1", "add", 1) # ban for 1 seconds + self.nodes[1].setban("2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/19", "add", 1000) # ban for 1000 seconds + listBeforeShutdown = self.nodes[1].listbanned() assert_equal("192.168.0.1/32", listBeforeShutdown[2]['address']) # must be here time.sleep(2) # make 100% sure we expired 192.168.0.1 node time # stop node - stop_node(self.nodes[2], 2) + stop_node(self.nodes[1], 1) - self.nodes[2] = start_node(2, self.options.tmpdir) - listAfterShutdown = self.nodes[2].listbanned() + self.nodes[1] = start_node(1, self.options.tmpdir) + listAfterShutdown = self.nodes[1].listbanned() assert_equal("127.0.0.0/24", listAfterShutdown[0]['address']) assert_equal("127.0.0.0/32", listAfterShutdown[1]['address']) assert_equal("/19" in listAfterShutdown[2]['address'], True) + # Clear ban lists + self.nodes[1].clearbanned() + connect_nodes_bi(self.nodes, 0, 1) + ########################### # RPC disconnectnode test # ########################### -- cgit v1.2.3 From 2077fdacd32adae8d118f019628ecdaa24632550 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Wed, 19 Apr 2017 11:30:36 -0400 Subject: [tests] disconnect_ban: add logging --- test/functional/disconnect_ban.py | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/test/functional/disconnect_ban.py b/test/functional/disconnect_ban.py index cb4efc8f45..4c50f85aee 100755 --- a/test/functional/disconnect_ban.py +++ b/test/functional/disconnect_ban.py @@ -27,32 +27,39 @@ class DisconnectBanTest(BitcoinTestFramework): connect_nodes_bi(self.nodes, 0, 1) def run_test(self): - ########################### - # setban/listbanned tests # - ########################### + self.log.info("Test setban and listbanned RPCs") + + self.log.info("setban: successfully ban single IP address") assert_equal(len(self.nodes[1].getpeerinfo()), 2) # node1 should have 2 connections to node0 at this point self.nodes[1].setban("127.0.0.1", "add") time.sleep(3) # wait till the nodes are disconected assert_equal(len(self.nodes[1].getpeerinfo()), 0) # all nodes must be disconnected at this point assert_equal(len(self.nodes[1].listbanned()), 1) + + self.log.info("clearbanned: successfully clear ban list") self.nodes[1].clearbanned() assert_equal(len(self.nodes[1].listbanned()), 0) self.nodes[1].setban("127.0.0.0/24", "add") + + self.log.info("setban: fail to ban an already banned subnet") assert_equal(len(self.nodes[1].listbanned()), 1) - # This will throw an exception because 127.0.0.1 is within range 127.0.0.0/24 assert_raises_jsonrpc(-23, "IP/Subnet already banned", self.nodes[1].setban, "127.0.0.1", "add") - # This will throw an exception because 127.0.0.1/42 is not a real subnet + + self.log.info("setban: fail to ban an invalid subnet") assert_raises_jsonrpc(-30, "Error: Invalid IP/Subnet", self.nodes[1].setban, "127.0.0.1/42", "add") assert_equal(len(self.nodes[1].listbanned()), 1) # still only one banned ip because 127.0.0.1 is within the range of 127.0.0.0/24 - # This will throw an exception because 127.0.0.1 was not added above + + self.log.info("setban remove: fail to unban a non-banned subnet") assert_raises_jsonrpc(-30, "Error: Unban failed", self.nodes[1].setban, "127.0.0.1", "remove") assert_equal(len(self.nodes[1].listbanned()), 1) + + self.log.info("setban remove: successfully unban subnet") self.nodes[1].setban("127.0.0.0/24", "remove") assert_equal(len(self.nodes[1].listbanned()), 0) self.nodes[1].clearbanned() assert_equal(len(self.nodes[1].listbanned()), 0) - # test persisted banlist + self.log.info("setban: test persistence across node restart") self.nodes[1].setban("127.0.0.0/32", "add") self.nodes[1].setban("127.0.0.0/24", "add") self.nodes[1].setban("192.168.0.1", "add", 1) # ban for 1 seconds @@ -74,15 +81,16 @@ class DisconnectBanTest(BitcoinTestFramework): self.nodes[1].clearbanned() connect_nodes_bi(self.nodes, 0, 1) - ########################### - # RPC disconnectnode test # - ########################### + self.log.info("Test disconnectrnode RPCs") + + self.log.info("disconnectnode: successfully disconnect node") url = urllib.parse.urlparse(self.nodes[1].url) self.nodes[0].disconnectnode(url.hostname + ":" + str(p2p_port(1))) time.sleep(2) # disconnecting a node needs a little bit of time for node in self.nodes[0].getpeerinfo(): assert(node['addr'] != url.hostname + ":" + str(p2p_port(1))) + self.log.info("disconnectnode: successfully reconnect node") connect_nodes_bi(self.nodes, 0, 1) # reconnect the node found = False for node in self.nodes[0].getpeerinfo(): -- cgit v1.2.3 From 12de2f252c8f48e05c579cb679866a68af8c660e Mon Sep 17 00:00:00 2001 From: John Newbery Date: Wed, 19 Apr 2017 12:42:39 -0400 Subject: [tests] disconnect_ban: use wait_until instead of sleep --- test/functional/disconnect_ban.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/test/functional/disconnect_ban.py b/test/functional/disconnect_ban.py index 4c50f85aee..c3ca2aee9b 100755 --- a/test/functional/disconnect_ban.py +++ b/test/functional/disconnect_ban.py @@ -3,9 +3,9 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test node disconnect and ban behavior""" -import time import urllib.parse +from test_framework.mininode import wait_until from test_framework.test_framework import BitcoinTestFramework from test_framework.util import (assert_equal, assert_raises_jsonrpc, @@ -32,7 +32,7 @@ class DisconnectBanTest(BitcoinTestFramework): self.log.info("setban: successfully ban single IP address") assert_equal(len(self.nodes[1].getpeerinfo()), 2) # node1 should have 2 connections to node0 at this point self.nodes[1].setban("127.0.0.1", "add") - time.sleep(3) # wait till the nodes are disconected + wait_until(lambda: len(self.nodes[1].getpeerinfo()) == 0) assert_equal(len(self.nodes[1].getpeerinfo()), 0) # all nodes must be disconnected at this point assert_equal(len(self.nodes[1].listbanned()), 1) @@ -65,10 +65,9 @@ class DisconnectBanTest(BitcoinTestFramework): self.nodes[1].setban("192.168.0.1", "add", 1) # ban for 1 seconds self.nodes[1].setban("2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/19", "add", 1000) # ban for 1000 seconds listBeforeShutdown = self.nodes[1].listbanned() - assert_equal("192.168.0.1/32", listBeforeShutdown[2]['address']) # must be here - time.sleep(2) # make 100% sure we expired 192.168.0.1 node time + assert_equal("192.168.0.1/32", listBeforeShutdown[2]['address']) + wait_until(lambda: len(self.nodes[1].listbanned()) == 3) - # stop node stop_node(self.nodes[1], 1) self.nodes[1] = start_node(1, self.options.tmpdir) @@ -86,7 +85,7 @@ class DisconnectBanTest(BitcoinTestFramework): self.log.info("disconnectnode: successfully disconnect node") url = urllib.parse.urlparse(self.nodes[1].url) self.nodes[0].disconnectnode(url.hostname + ":" + str(p2p_port(1))) - time.sleep(2) # disconnecting a node needs a little bit of time + wait_until(lambda: len(self.nodes[0].getpeerinfo()) == 1) for node in self.nodes[0].getpeerinfo(): assert(node['addr'] != url.hostname + ":" + str(p2p_port(1))) -- cgit v1.2.3 From 5cc3ee24d29397737f2746d78b19a2509c0dedbb Mon Sep 17 00:00:00 2001 From: John Newbery Date: Wed, 19 Apr 2017 13:35:51 -0400 Subject: [tests] disconnect_ban: remove dependency on urllib --- test/functional/disconnect_ban.py | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/test/functional/disconnect_ban.py b/test/functional/disconnect_ban.py index c3ca2aee9b..aeb4199c0f 100755 --- a/test/functional/disconnect_ban.py +++ b/test/functional/disconnect_ban.py @@ -3,14 +3,12 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test node disconnect and ban behavior""" -import urllib.parse from test_framework.mininode import wait_until from test_framework.test_framework import BitcoinTestFramework from test_framework.util import (assert_equal, assert_raises_jsonrpc, connect_nodes_bi, - p2p_port, start_node, stop_node, ) @@ -82,20 +80,15 @@ class DisconnectBanTest(BitcoinTestFramework): self.log.info("Test disconnectrnode RPCs") - self.log.info("disconnectnode: successfully disconnect node") - url = urllib.parse.urlparse(self.nodes[1].url) - self.nodes[0].disconnectnode(url.hostname + ":" + str(p2p_port(1))) + self.log.info("disconnectnode: successfully disconnect node by address") + address1 = self.nodes[0].getpeerinfo()[0]['addr'] + self.nodes[0].disconnectnode(address=address1) wait_until(lambda: len(self.nodes[0].getpeerinfo()) == 1) - for node in self.nodes[0].getpeerinfo(): - assert(node['addr'] != url.hostname + ":" + str(p2p_port(1))) + assert not [node for node in self.nodes[0].getpeerinfo() if node['addr'] == address1] self.log.info("disconnectnode: successfully reconnect node") connect_nodes_bi(self.nodes, 0, 1) # reconnect the node - found = False - for node in self.nodes[0].getpeerinfo(): - if node['addr'] == url.hostname + ":" + str(p2p_port(1)): - found = True - assert(found) + assert [node for node in self.nodes[0].getpeerinfo() if node['addr'] == address1] if __name__ == '__main__': DisconnectBanTest().main() -- cgit v1.2.3 From d54297f1a85612dab100c473ad04c4f9d279f473 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Wed, 19 Apr 2017 13:44:16 -0400 Subject: [tests] disconnect_ban: add tests for disconnect-by-nodeid --- test/functional/disconnect_ban.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/functional/disconnect_ban.py b/test/functional/disconnect_ban.py index aeb4199c0f..3f451d49d2 100755 --- a/test/functional/disconnect_ban.py +++ b/test/functional/disconnect_ban.py @@ -80,6 +80,14 @@ class DisconnectBanTest(BitcoinTestFramework): self.log.info("Test disconnectrnode RPCs") + self.log.info("disconnectnode: fail to disconnect when calling with address and nodeid") + address1 = self.nodes[0].getpeerinfo()[0]['addr'] + node1 = self.nodes[0].getpeerinfo()[0]['addr'] + assert_raises_jsonrpc(-32602, "Only one of address and nodeid should be provided.", self.nodes[0].disconnectnode, address=address1, nodeid=node1) + + self.log.info("disconnectnode: fail to disconnect when calling with junk address") + assert_raises_jsonrpc(-29, "Node not found in connected nodes", self.nodes[0].disconnectnode, address="221B Baker Street") + self.log.info("disconnectnode: successfully disconnect node by address") address1 = self.nodes[0].getpeerinfo()[0]['addr'] self.nodes[0].disconnectnode(address=address1) @@ -88,7 +96,14 @@ class DisconnectBanTest(BitcoinTestFramework): self.log.info("disconnectnode: successfully reconnect node") connect_nodes_bi(self.nodes, 0, 1) # reconnect the node + assert_equal(len(self.nodes[0].getpeerinfo()), 2) assert [node for node in self.nodes[0].getpeerinfo() if node['addr'] == address1] + self.log.info("disconnectnode: successfully disconnect node by node id") + id1 = self.nodes[0].getpeerinfo()[0]['id'] + self.nodes[0].disconnectnode(nodeid=id1) + wait_until(lambda: len(self.nodes[0].getpeerinfo()) == 1) + assert not [node for node in self.nodes[0].getpeerinfo() if node['id'] == id1] + if __name__ == '__main__': DisconnectBanTest().main() -- cgit v1.2.3