From 8e057ad9ee89611227c7b180c61ebd4de8d9a541 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 12 Sep 2018 12:11:10 +0100 Subject: [PATCH] qa: Test both Overwinter and Sapling peer management --- qa/pull-tester/rpc-tests.sh | 2 +- qa/rpc-tests/overwinter_peer_management.py | 118 ------------- qa/rpc-tests/p2p_nu_peer_management.py | 192 +++++++++++++++++++++ qa/rpc-tests/test_framework/mininode.py | 3 +- 4 files changed, 195 insertions(+), 120 deletions(-) delete mode 100755 qa/rpc-tests/overwinter_peer_management.py create mode 100755 qa/rpc-tests/p2p_nu_peer_management.py diff --git a/qa/pull-tester/rpc-tests.sh b/qa/pull-tester/rpc-tests.sh index 25ecc409a..0bc6fefaa 100755 --- a/qa/pull-tester/rpc-tests.sh +++ b/qa/pull-tester/rpc-tests.sh @@ -57,7 +57,7 @@ testScripts=( 'getblocktemplate.py' 'bip65-cltv-p2p.py' 'bipdersig-p2p.py' - 'overwinter_peer_management.py' + 'p2p_nu_peer_management.py' 'rewind_index.py' 'p2p_txexpiry_dos.py' 'p2p_node_bloom.py' diff --git a/qa/rpc-tests/overwinter_peer_management.py b/qa/rpc-tests/overwinter_peer_management.py deleted file mode 100755 index a5017b8b0..000000000 --- a/qa/rpc-tests/overwinter_peer_management.py +++ /dev/null @@ -1,118 +0,0 @@ -#!/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_ping, SPROUT_PROTO_VERSION, OVERWINTER_PROTO_VERSION -from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import initialize_chain_clean, start_nodes, \ - p2p_port, assert_equal - -import time - -# -# In this test we connect Sprout and Overwinter mininodes to a Zcashd node -# which will activate Overwinter at block 10. -# -# We test: -# 1. the mininodes stay connected to Zcash with Sprout consensus rules -# 2. when Overwinter activates, the Sprout mininodes are dropped -# 3. new Overwinter nodes can connect to Zcash -# 4. new Sprout nodes cannot connect to Zcash -# -# This test *does not* verify that prior to Overwinter activation, the Zcashd -# node will prefer connections with Overwinter nodes, with an eviction process -# that prioritizes Sprout connections. -# - - -class TestManager(NodeConnCB): - def __init__(self): - NodeConnCB.__init__(self) - self.create_callback_map() - - def on_close(self, conn): - pass - - def on_reject(self, conn, message): - conn.rejectMessage = message - - -class OverwinterPeerManagementTest(BitcoinTestFramework): - - def setup_chain(self): - print "Initializing test directory "+self.options.tmpdir - initialize_chain_clean(self.options.tmpdir, 1) - - def setup_network(self): - self.nodes = start_nodes(1, self.options.tmpdir, - extra_args=[['-nuparams=5ba81b19:10', '-debug', '-whitelist=127.0.0.1']]) - - def run_test(self): - test = TestManager() - - # Launch 10 Sprout and 10 Overwinter mininodes - nodes = [] - for x in xrange(10): - nodes.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], - test, "regtest", SPROUT_PROTO_VERSION)) - nodes.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], - test, "regtest", OVERWINTER_PROTO_VERSION)) - - # Start up network handling in another thread - NetworkThread().start() - - # Sprout consensus rules apply at block height 9 - self.nodes[0].generate(9) - assert_equal(9, self.nodes[0].getblockcount()) - - # Verify mininodes are still connected to zcashd node - peerinfo = self.nodes[0].getpeerinfo() - versions = [x["version"] for x in peerinfo] - assert_equal(10, versions.count(SPROUT_PROTO_VERSION)) - assert_equal(10, versions.count(OVERWINTER_PROTO_VERSION)) - - # Overwinter consensus rules activate at block height 10 - self.nodes[0].generate(1) - assert_equal(10, self.nodes[0].getblockcount()) - - # Mininodes send ping message to zcashd node. - pingCounter = 1 - for node in nodes: - node.send_message(msg_ping(pingCounter)) - pingCounter = pingCounter + 1 - - time.sleep(3) - - # Verify Sprout mininodes have been dropped and Overwinter mininodes are still connected. - peerinfo = self.nodes[0].getpeerinfo() - versions = [x["version"] for x in peerinfo] - assert_equal(0, versions.count(SPROUT_PROTO_VERSION)) - assert_equal(10, versions.count(OVERWINTER_PROTO_VERSION)) - - # Extend the Overwinter chain with another block. - self.nodes[0].generate(1) - - # Connect a new Overwinter mininode to the zcashd node, which is accepted. - nodes.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test, "regtest", OVERWINTER_PROTO_VERSION)) - time.sleep(3) - assert_equal(11, len(self.nodes[0].getpeerinfo())) - - # Try to connect a new Sprout mininode to the zcashd node, which is rejected. - sprout = NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test, "regtest", SPROUT_PROTO_VERSION) - nodes.append(sprout) - time.sleep(3) - assert("Version must be 170003 or greater" in str(sprout.rejectMessage)) - - # Verify that only Overwinter mininodes are connected. - peerinfo = self.nodes[0].getpeerinfo() - versions = [x["version"] for x in peerinfo] - assert_equal(0, versions.count(SPROUT_PROTO_VERSION)) - assert_equal(11, versions.count(OVERWINTER_PROTO_VERSION)) - - for node in nodes: - node.disconnect_node() - -if __name__ == '__main__': - OverwinterPeerManagementTest().main() diff --git a/qa/rpc-tests/p2p_nu_peer_management.py b/qa/rpc-tests/p2p_nu_peer_management.py new file mode 100755 index 000000000..6cedf66bb --- /dev/null +++ b/qa/rpc-tests/p2p_nu_peer_management.py @@ -0,0 +1,192 @@ +#!/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_ping, + SPROUT_PROTO_VERSION, + OVERWINTER_PROTO_VERSION, + SAPLING_PROTO_VERSION, +) +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import initialize_chain_clean, start_nodes, \ + p2p_port, assert_equal + +import time + +# +# In this test we connect Sprout, Overwinter, and Sapling mininodes to a Zcashd +# node which will activate Overwinter at block 10 and Sapling at block 15. +# +# We test: +# 1. the mininodes stay connected to Zcash with Sprout consensus rules +# 2. when Overwinter activates, the Sprout mininodes are dropped +# 3. new Overwinter and Sapling nodes can connect to Zcash +# 4. new Sprout nodes cannot connect to Zcash +# 5. when Sapling activates, the Overwinter mininodes are dropped +# 6. new Sapling nodes can connect to Zcash +# 7. new Sprout and Overwinter nodes cannot connect to Zcash +# +# This test *does not* verify that prior to each activation, the Zcashd +# node will prefer connections with NU-aware nodes, with an eviction process +# that prioritizes non-NU-aware connections. +# + + +class TestManager(NodeConnCB): + def __init__(self): + NodeConnCB.__init__(self) + self.create_callback_map() + + def on_close(self, conn): + pass + + def on_reject(self, conn, message): + conn.rejectMessage = message + + +class NUPeerManagementTest(BitcoinTestFramework): + + def setup_chain(self): + print "Initializing test directory "+self.options.tmpdir + initialize_chain_clean(self.options.tmpdir, 1) + + def setup_network(self): + self.nodes = start_nodes(1, self.options.tmpdir, extra_args=[[ + '-nuparams=5ba81b19:10', # Overwinter + '-nuparams=76b809bb:15', # Sapling + '-debug', + '-whitelist=127.0.0.1', + ]]) + + def run_test(self): + test = TestManager() + + # Launch Sprout, Overwinter, and Sapling mininodes + nodes = [] + for x in xrange(10): + nodes.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], + test, "regtest", SPROUT_PROTO_VERSION)) + nodes.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], + test, "regtest", OVERWINTER_PROTO_VERSION)) + nodes.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], + test, "regtest", SAPLING_PROTO_VERSION)) + + # Start up network handling in another thread + NetworkThread().start() + + # Sprout consensus rules apply at block height 9 + self.nodes[0].generate(9) + assert_equal(9, self.nodes[0].getblockcount()) + + # Verify mininodes are still connected to zcashd node + peerinfo = self.nodes[0].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(10, versions.count(SPROUT_PROTO_VERSION)) + assert_equal(10, versions.count(OVERWINTER_PROTO_VERSION)) + assert_equal(10, versions.count(SAPLING_PROTO_VERSION)) + + # Overwinter consensus rules activate at block height 10 + self.nodes[0].generate(1) + assert_equal(10, self.nodes[0].getblockcount()) + print('Overwinter active') + + # Mininodes send ping message to zcashd node. + pingCounter = 1 + for node in nodes: + node.send_message(msg_ping(pingCounter)) + pingCounter = pingCounter + 1 + + time.sleep(3) + + # Verify Sprout mininodes have been dropped, while Overwinter and + # Sapling mininodes are still connected. + peerinfo = self.nodes[0].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(0, versions.count(SPROUT_PROTO_VERSION)) + assert_equal(10, versions.count(OVERWINTER_PROTO_VERSION)) + assert_equal(10, versions.count(SAPLING_PROTO_VERSION)) + + # Extend the Overwinter chain with another block. + self.nodes[0].generate(1) + + # Connect a new Overwinter mininode to the zcashd node, which is accepted. + nodes.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test, "regtest", OVERWINTER_PROTO_VERSION)) + time.sleep(3) + assert_equal(21, len(self.nodes[0].getpeerinfo())) + + # Connect a new Sapling mininode to the zcashd node, which is accepted. + nodes.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test, "regtest", SAPLING_PROTO_VERSION)) + time.sleep(3) + assert_equal(22, len(self.nodes[0].getpeerinfo())) + + # Try to connect a new Sprout mininode to the zcashd node, which is rejected. + sprout = NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test, "regtest", SPROUT_PROTO_VERSION) + nodes.append(sprout) + time.sleep(3) + assert("Version must be 170003 or greater" in str(sprout.rejectMessage)) + + # Verify that only Overwinter and Sapling mininodes are connected. + peerinfo = self.nodes[0].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(0, versions.count(SPROUT_PROTO_VERSION)) + assert_equal(11, versions.count(OVERWINTER_PROTO_VERSION)) + assert_equal(11, versions.count(SAPLING_PROTO_VERSION)) + + # Sapling consensus rules activate at block height 15 + self.nodes[0].generate(4) + assert_equal(15, self.nodes[0].getblockcount()) + print('Sapling active') + + # Mininodes send ping message to zcashd node. + pingCounter = 1 + for node in nodes: + node.send_message(msg_ping(pingCounter)) + pingCounter = pingCounter + 1 + + time.sleep(3) + + # Verify Sprout and Overwinter mininodes have been dropped, while + # Sapling mininodes are still connected. + peerinfo = self.nodes[0].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(0, versions.count(SPROUT_PROTO_VERSION)) + assert_equal(0, versions.count(OVERWINTER_PROTO_VERSION)) + assert_equal(11, versions.count(SAPLING_PROTO_VERSION)) + + # Extend the Sapling chain with another block. + self.nodes[0].generate(1) + + # Connect a new Sapling mininode to the zcashd node, which is accepted. + nodes.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test, "regtest", SAPLING_PROTO_VERSION)) + time.sleep(3) + assert_equal(12, len(self.nodes[0].getpeerinfo())) + + # Try to connect a new Sprout mininode to the zcashd node, which is rejected. + sprout = NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test, "regtest", SPROUT_PROTO_VERSION) + nodes.append(sprout) + time.sleep(3) + assert("Version must be 170006 or greater" in str(sprout.rejectMessage)) + + # Try to connect a new Overwinter mininode to the zcashd node, which is rejected. + sprout = NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test, "regtest", OVERWINTER_PROTO_VERSION) + nodes.append(sprout) + time.sleep(3) + assert("Version must be 170006 or greater" in str(sprout.rejectMessage)) + + # Verify that only Sapling mininodes are connected. + peerinfo = self.nodes[0].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(0, versions.count(SPROUT_PROTO_VERSION)) + assert_equal(0, versions.count(OVERWINTER_PROTO_VERSION)) + assert_equal(12, versions.count(SAPLING_PROTO_VERSION)) + + for node in nodes: + node.disconnect_node() + +if __name__ == '__main__': + NUPeerManagementTest().main() diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index 39b634a5e..cd29c1791 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -42,6 +42,7 @@ from .equihash import ( OVERWINTER_PROTO_VERSION = 170003 BIP0031_VERSION = 60000 SPROUT_PROTO_VERSION = 170002 # past bip-31 for ping/pong +SAPLING_PROTO_VERSION = 170006 MY_SUBVERSION = "/python-mininode-tester:0.0.1/" OVERWINTER_VERSION_GROUP_ID = 0x03C48270 @@ -1415,7 +1416,7 @@ class NodeConn(asyncore.dispatcher): vt.addrFrom.port = 0 self.send_message(vt, True) print 'MiniNode: Connecting to Bitcoin Node IP # ' + dstaddr + ':' \ - + str(dstport) + + str(dstport) + ' using version ' + str(protocol_version) try: self.connect((dstaddr, dstport))