From b77e46fe018a2c3e6699dc5d79cb7754251029b6 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Tue, 3 Apr 2018 17:12:46 +0100 Subject: [PATCH] Add RPC test for -enforcenodebloom --- qa/pull-tester/rpc-tests.sh | 1 + qa/rpc-tests/p2p_node_bloom.py | 97 +++++++++++++++++++++++++ qa/rpc-tests/test_framework/mininode.py | 16 ++++ 3 files changed, 114 insertions(+) create mode 100755 qa/rpc-tests/p2p_node_bloom.py diff --git a/qa/pull-tester/rpc-tests.sh b/qa/pull-tester/rpc-tests.sh index 9900b1c20..729c92b1d 100755 --- a/qa/pull-tester/rpc-tests.sh +++ b/qa/pull-tester/rpc-tests.sh @@ -57,6 +57,7 @@ testScripts=( 'overwinter_peer_management.py' 'rewind_index.py' 'p2p_txexpiry_dos.py' + 'p2p_node_bloom.py' ); testScriptsExt=( 'getblocktemplate_longpoll.py' diff --git a/qa/rpc-tests/p2p_node_bloom.py b/qa/rpc-tests/p2p_node_bloom.py new file mode 100755 index 000000000..2e0d60e4e --- /dev/null +++ b/qa/rpc-tests/p2p_node_bloom.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python2 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.mininode import NodeConn, NodeConnCB, NetworkThread, \ + msg_filterclear, mininode_lock, MY_VERSION +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import initialize_chain_clean, start_nodes, \ + p2p_port, assert_equal + +import time + + +class TestNode(NodeConnCB): + def __init__(self): + NodeConnCB.__init__(self) + self.create_callback_map() + self.connection = None + + def add_connection(self, conn): + self.connection = conn + + # Spin until verack message is received from the node. + # We use this to signal that our test can begin. This + # is called from the testing thread, so it needs to acquire + # the global lock. + def wait_for_verack(self): + while True: + with mininode_lock: + if self.verack_received: + return + time.sleep(0.05) + + # Wrapper for the NodeConn's send_message function + def send_message(self, message): + self.connection.send_message(message) + + def on_close(self, conn): + pass + + def on_reject(self, conn, message): + conn.rejectMessage = message + + +class NodeBloomTest(BitcoinTestFramework): + + def setup_chain(self): + print "Initializing test directory "+self.options.tmpdir + initialize_chain_clean(self.options.tmpdir, 2) + + def setup_network(self): + self.nodes = start_nodes(2, self.options.tmpdir, + extra_args=[['-nopeerbloomfilters', '-enforcenodebloom'], []]) + + def run_test(self): + nobf_node = TestNode() + bf_node = TestNode() + + connections = [] + connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], nobf_node)) + connections.append(NodeConn('127.0.0.1', p2p_port(1), self.nodes[1], bf_node)) + nobf_node.add_connection(connections[0]) + bf_node.add_connection(connections[1]) + + # Start up network handling in another thread + NetworkThread().start() + + nobf_node.wait_for_verack() + bf_node.wait_for_verack() + + # Verify mininodes are connected to zcashd nodes + peerinfo = self.nodes[0].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(1, versions.count(MY_VERSION)) + peerinfo = self.nodes[1].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(1, versions.count(MY_VERSION)) + + # Mininodes send filterclear message to zcashd node. + nobf_node.send_message(msg_filterclear()) + bf_node.send_message(msg_filterclear()) + + time.sleep(3) + + # Verify NoBF mininode has been dropped, and BF mininode is still connected. + peerinfo = self.nodes[0].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(0, versions.count(MY_VERSION)) + peerinfo = self.nodes[1].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(1, versions.count(MY_VERSION)) + + [ c.disconnect_node() for c in connections ] + +if __name__ == '__main__': + NodeBloomTest().main() diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index 12b48ae0b..e0f2a3844 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -1263,6 +1263,22 @@ class msg_reject(object): % (self.message, self.code, self.reason, self.data) +class msg_filterclear(object): + command = "filterclear" + + def __init__(self): + pass + + def deserialize(self, f): + pass + + def serialize(self): + return "" + + def __repr__(self): + return "msg_filterclear()" + + # This is what a callback should look like for NodeConn # Reimplement the on_* functions to provide handling for events class NodeConnCB(object):