diff --git a/qa/rpc-tests/p2p_txexpiringsoon.py b/qa/rpc-tests/p2p_txexpiringsoon.py index 26641dbeb..7b63d3873 100755 --- a/qa/rpc-tests/p2p_txexpiringsoon.py +++ b/qa/rpc-tests/p2p_txexpiringsoon.py @@ -6,78 +6,14 @@ import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." from test_framework.authproxy import JSONRPCException -from test_framework.mininode import NodeConn, NodeConnCB, NetworkThread, \ - CTransaction, CInv, msg_mempool, msg_getdata, msg_tx, mininode_lock, \ - msg_ping, msg_pong, OVERWINTER_PROTO_VERSION +from test_framework.mininode import NodeConn, NetworkThread, CInv, \ + msg_mempool, msg_getdata, msg_tx, mininode_lock, OVERWINTER_PROTO_VERSION from test_framework.test_framework import BitcoinTestFramework from test_framework.util import initialize_chain_clean, start_nodes, \ p2p_port, assert_equal, sync_blocks, sync_mempools, connect_nodes_bi +from tx_expiry_helper import TestNode, create_transaction -import time, cStringIO -from binascii import hexlify, unhexlify - - -class TestNode(NodeConnCB): - def __init__(self): - NodeConnCB.__init__(self) - self.create_callback_map() - self.connection = None - self.ping_counter = 1 - self.last_pong = msg_pong() - - 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 - - # Track the last getdata message we receive (used in the test) - def on_getdata(self, conn, message): - self.last_getdata = message - - def on_tx(self, conn, message): - self.last_tx = message - - def on_inv(self, conn, message): - self.last_inv = message - - def on_notfound(self, conn, message): - self.last_notfound = message - - def on_pong(self, conn, message): - self.last_pong = message - - # Sync up with the node after delivery of a message - def sync_with_ping(self, timeout=30): - self.connection.send_message(msg_ping(nonce=self.ping_counter)) - received_pong = False - sleep_time = 0.05 - while not received_pong and timeout > 0: - time.sleep(sleep_time) - timeout -= sleep_time - with mininode_lock: - if self.last_pong.nonce == self.ping_counter: - received_pong = True - self.ping_counter += 1 - return received_pong +from binascii import hexlify class TxExpiringSoonTest(BitcoinTestFramework): @@ -92,25 +28,6 @@ class TxExpiringSoonTest(BitcoinTestFramework): connect_nodes_bi(self.nodes, 0, 1) # We don't connect node 2 - def create_transaction(self, node, coinbase, to_address, amount, expiry_height): - from_txid = node.getblock(coinbase)['tx'][0] - inputs = [{"txid": from_txid, "vout": 0}] - outputs = {to_address: amount} - rawtx = node.createrawtransaction(inputs, outputs) - tx = CTransaction() - - # Set the expiry height - f = cStringIO.StringIO(unhexlify(rawtx)) - tx.deserialize(f) - tx.nExpiryHeight = expiry_height - rawtx = hexlify(tx.serialize()) - - signresult = node.signrawtransaction(rawtx) - f = cStringIO.StringIO(unhexlify(signresult['hex'])) - tx.deserialize(f) - tx.rehash() - return tx - def run_test(self): testnode0 = TestNode() connections = [] @@ -142,17 +59,19 @@ class TxExpiringSoonTest(BitcoinTestFramework): assert_equal(self.nodes[2].getblockcount(), 0) # Mininodes send expiring soon transaction in "tx" message to zcashd node - tx1 = self.create_transaction(self.nodes[0], - self.coinbase_blocks[0], - self.nodeaddress, 10.0, - 203) + tx1 = create_transaction(self.nodes[0], + self.coinbase_blocks[0], + self.nodeaddress, + 10.0, + 203) testnode0.send_message(msg_tx(tx1)) # Mininodes send transaction in "tx" message to zcashd node - tx2 = self.create_transaction(self.nodes[0], - self.coinbase_blocks[1], - self.nodeaddress, 10.0, - 204) + tx2 = create_transaction(self.nodes[0], + self.coinbase_blocks[1], + self.nodeaddress, + 10.0, + 204) testnode0.send_message(msg_tx(tx2)) # Sync up with node after p2p messages delivered @@ -259,10 +178,11 @@ class TxExpiringSoonTest(BitcoinTestFramework): assert_equal(tx2.sha256, msg.inv[0].hash) # Create a transaction to verify that processing of "getdata" messages is functioning - tx3 = self.create_transaction(self.nodes[0], - self.coinbase_blocks[2], - self.nodeaddress, 10.0, - 999) + tx3 = create_transaction(self.nodes[0], + self.coinbase_blocks[2], + self.nodeaddress, + 10.0, + 999) # Mininodes send tx3 to zcashd node testnode0.send_message(msg_tx(tx3)) diff --git a/qa/rpc-tests/p2p_txexpiry_dos.py b/qa/rpc-tests/p2p_txexpiry_dos.py index 3c027e4c2..c7b5f3056 100755 --- a/qa/rpc-tests/p2p_txexpiry_dos.py +++ b/qa/rpc-tests/p2p_txexpiry_dos.py @@ -5,45 +5,14 @@ import sys; assert sys.version_info < (3,), ur"This script does not run under Python 3. Please use Python 2.7.x." -from test_framework.mininode import NodeConn, NodeConnCB, NetworkThread, \ - CTransaction, msg_tx, mininode_lock, OVERWINTER_PROTO_VERSION +from test_framework.mininode import NodeConn, NetworkThread, \ + msg_tx, OVERWINTER_PROTO_VERSION from test_framework.test_framework import BitcoinTestFramework from test_framework.util import initialize_chain_clean, start_nodes, \ p2p_port, assert_equal +from tx_expiry_helper import TestNode, create_transaction -import time, cStringIO -from binascii import hexlify, unhexlify - - -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 +import time class TxExpiryDoSTest(BitcoinTestFramework): @@ -56,24 +25,6 @@ class TxExpiryDoSTest(BitcoinTestFramework): self.nodes = start_nodes(1, self.options.tmpdir, extra_args=[['-nuparams=5ba81b19:10']]) - def create_transaction(self, node, coinbase, to_address, amount, txModifier=None): - from_txid = node.getblock(coinbase)['tx'][0] - inputs = [{"txid": from_txid, "vout": 0}] - outputs = {to_address: amount} - rawtx = node.createrawtransaction(inputs, outputs) - tx = CTransaction() - - if txModifier: - f = cStringIO.StringIO(unhexlify(rawtx)) - tx.deserialize(f) - txModifier(tx) - rawtx = hexlify(tx.serialize()) - - signresult = node.signrawtransaction(rawtx) - f = cStringIO.StringIO(unhexlify(signresult['hex'])) - tx.deserialize(f) - return tx - def run_test(self): test_node = TestNode() @@ -98,13 +49,11 @@ class TxExpiryDoSTest(BitcoinTestFramework): self.nodeaddress = self.nodes[0].getnewaddress() # Mininodes send transaction to zcashd node. - def setExpiryHeight(tx): - tx.nExpiryHeight = 101 - - spendtx = self.create_transaction(self.nodes[0], - self.coinbase_blocks[0], - self.nodeaddress, 1.0, - txModifier=setExpiryHeight) + spendtx = create_transaction(self.nodes[0], + self.coinbase_blocks[0], + self.nodeaddress, + 1.0, + 101) test_node.send_message(msg_tx(spendtx)) time.sleep(3) diff --git a/qa/rpc-tests/tx_expiry_helper.py b/qa/rpc-tests/tx_expiry_helper.py new file mode 100755 index 000000000..f0c028e59 --- /dev/null +++ b/qa/rpc-tests/tx_expiry_helper.py @@ -0,0 +1,98 @@ +# Copyright (c) 2019 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# +# Common code for testing transaction expiry +# +from test_framework.mininode import CTransaction, NodeConnCB, mininode_lock, msg_ping, \ + msg_pong + +import cStringIO +import time + +from binascii import hexlify, unhexlify + + +class TestNode(NodeConnCB): + def __init__(self): + NodeConnCB.__init__(self) + self.create_callback_map() + self.connection = None + self.ping_counter = 1 + self.last_pong = msg_pong() + + 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 + + # Track the last getdata message we receive (used in the test) + def on_getdata(self, conn, message): + self.last_getdata = message + + def on_tx(self, conn, message): + self.last_tx = message + + def on_inv(self, conn, message): + self.last_inv = message + + def on_notfound(self, conn, message): + self.last_notfound = message + + def on_pong(self, conn, message): + self.last_pong = message + + # The following function is copied from p2p-acceptblock.py + # Sync up with the node after delivery of a message + def sync_with_ping(self, timeout=30): + self.connection.send_message(msg_ping(nonce=self.ping_counter)) + received_pong = False + sleep_time = 0.05 + while not received_pong and timeout > 0: + time.sleep(sleep_time) + timeout -= sleep_time + with mininode_lock: + if self.last_pong.nonce == self.ping_counter: + received_pong = True + self.ping_counter += 1 + return received_pong + + +def create_transaction(node, coinbase, to_address, amount, expiry_height): + from_txid = node.getblock(coinbase)['tx'][0] + inputs = [{"txid": from_txid, "vout": 0}] + outputs = {to_address: amount} + rawtx = node.createrawtransaction(inputs, outputs) + tx = CTransaction() + + # Set the expiry height + f = cStringIO.StringIO(unhexlify(rawtx)) + tx.deserialize(f) + tx.nExpiryHeight = expiry_height + rawtx = hexlify(tx.serialize()) + + signresult = node.signrawtransaction(rawtx) + f = cStringIO.StringIO(unhexlify(signresult['hex'])) + tx.deserialize(f) + tx.rehash() + return tx