diff --git a/test/functional/p2p_filter.py b/test/functional/p2p_filter.py index b73d5784a..2eeb03bfa 100755 --- a/test/functional/p2p_filter.py +++ b/test/functional/p2p_filter.py @@ -60,8 +60,13 @@ class FilterTest(BitcoinTestFramework): self.skip_if_no_wallet() def run_test(self): - self.log.info('Add filtered P2P connection to the node') filter_node = self.nodes[0].add_p2p_connection(FilterNode()) + + self.log.info('Check that too large filter is rejected') + with self.nodes[0].assert_debug_log(['Misbehaving']): + filter_node.send_and_ping(msg_filterload(data=b'\xaa', nHashFuncs=51, nTweak=0, nFlags=1)) + + self.log.info('Add filtered P2P connection to the node') filter_node.send_and_ping(filter_node.watch_filter_init) filter_address = self.nodes[0].decodescript(filter_node.watch_script_pubkey)['addresses'][0] diff --git a/test/functional/p2p_invalid_messages.py b/test/functional/p2p_invalid_messages.py index 759f111e6..eaecaeeb3 100755 --- a/test/functional/p2p_invalid_messages.py +++ b/test/functional/p2p_invalid_messages.py @@ -8,7 +8,11 @@ import struct import sys from test_framework import messages -from test_framework.mininode import P2PDataStore, NetworkThread +from test_framework.mininode import ( + NetworkThread, + P2PDataStore, + P2PInterface, +) from test_framework.test_framework import BitcoinTestFramework @@ -47,6 +51,7 @@ class InvalidMessagesTest(BitcoinTestFramework): self.test_checksum() self.test_size() self.test_command() + self.test_large_inv() node = self.nodes[0] self.node = node @@ -198,6 +203,19 @@ class InvalidMessagesTest(BitcoinTestFramework): conn.sync_with_ping(timeout=1) self.nodes[0].disconnect_p2ps() + def test_large_inv(self): + conn = self.nodes[0].add_p2p_connection(P2PInterface()) + with self.nodes[0].assert_debug_log(['Misbehaving', 'peer=4 (0 -> 20): message inv size() = 50001']): + msg = messages.msg_inv([messages.CInv(1, 1)] * 50001) + conn.send_and_ping(msg) + with self.nodes[0].assert_debug_log(['Misbehaving', 'peer=4 (20 -> 40): message getdata size() = 50001']): + msg = messages.msg_getdata([messages.CInv(1, 1)] * 50001) + conn.send_and_ping(msg) + with self.nodes[0].assert_debug_log(['Misbehaving', 'peer=4 (40 -> 60): headers message size = 2001']): + msg = messages.msg_headers([messages.CBlockHeader()] * 2001) + conn.send_and_ping(msg) + self.nodes[0].disconnect_p2ps() + def _tweak_msg_data_size(self, message, wrong_size): """ Return a raw message based on another message but with an incorrect data size in diff --git a/test/functional/p2p_invalid_tx.py b/test/functional/p2p_invalid_tx.py index 5975a52b2..c904c57c9 100755 --- a/test/functional/p2p_invalid_tx.py +++ b/test/functional/p2p_invalid_tx.py @@ -118,6 +118,7 @@ class InvalidTxRequestTest(BitcoinTestFramework): tx_orphan_2_invalid = CTransaction() tx_orphan_2_invalid.vin.append(CTxIn(outpoint=COutPoint(tx_orphan_1.sha256, 2))) tx_orphan_2_invalid.vout.append(CTxOut(nValue=11 * COIN, scriptPubKey=SCRIPT_PUB_KEY_OP_TRUE)) + tx_orphan_2_invalid.calc_sha256() self.log.info('Send the orphans ... ') # Send valid orphan txs from p2ps[0] @@ -148,6 +149,22 @@ class InvalidTxRequestTest(BitcoinTestFramework): wait_until(lambda: 1 == len(node.getpeerinfo()), timeout=12) # p2ps[1] is no longer connected assert_equal(expected_mempool, set(node.getrawmempool())) + self.log.info('Test orphan pool overflow') + orphan_tx_pool = [CTransaction() for _ in range(101)] + for i in range(len(orphan_tx_pool)): + orphan_tx_pool[i].vin.append(CTxIn(outpoint=COutPoint(i, 333))) + orphan_tx_pool[i].vout.append(CTxOut(nValue=11 * COIN, scriptPubKey=SCRIPT_PUB_KEY_OP_TRUE)) + + with node.assert_debug_log(['mapOrphan overflow, removed 1 tx']): + node.p2p.send_txs_and_test(orphan_tx_pool, node, success=False) + + rejected_parent = CTransaction() + rejected_parent.vin.append(CTxIn(outpoint=COutPoint(tx_orphan_2_invalid.sha256, 0))) + rejected_parent.vout.append(CTxOut(nValue=11 * COIN, scriptPubKey=SCRIPT_PUB_KEY_OP_TRUE)) + rejected_parent.rehash() + with node.assert_debug_log(['not keeping orphan with rejected parents {}'.format(rejected_parent.hash)]): + node.p2p.send_txs_and_test([rejected_parent], node, success=False) + if __name__ == '__main__': InvalidTxRequestTest().main() diff --git a/test/functional/p2p_leak.py b/test/functional/p2p_leak.py index c574c1ab9..76f33574a 100755 --- a/test/functional/p2p_leak.py +++ b/test/functional/p2p_leak.py @@ -12,7 +12,12 @@ into sending us something it shouldn't.""" import time -from test_framework.messages import msg_getaddr, msg_ping, msg_verack +from test_framework.messages import ( + msg_getaddr, + msg_ping, + msg_verack, + msg_version, +) from test_framework.mininode import mininode_lock, P2PInterface from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( @@ -147,6 +152,15 @@ class P2PLeakTest(BitcoinTestFramework): assert_equal(ver.nStartingHeight, 201) assert_equal(ver.nRelay, 1) + self.log.info('Check that old nodes are disconnected') + p2p_old_node = self.nodes[0].add_p2p_connection(P2PInterface(), send_version=False, wait_for_verack=False) + old_version_msg = msg_version() + old_version_msg.nVersion = 31799 + wait_until(lambda: p2p_old_node.is_connected) + with self.nodes[0].assert_debug_log(['peer=4 using obsolete version 31799; disconnecting']): + p2p_old_node.send_message(old_version_msg) + p2p_old_node.wait_for_disconnect() + if __name__ == '__main__': P2PLeakTest().main() diff --git a/test/functional/p2p_tx_download.py b/test/functional/p2p_tx_download.py index b56dc994e..1d74c757d 100755 --- a/test/functional/p2p_tx_download.py +++ b/test/functional/p2p_tx_download.py @@ -152,6 +152,10 @@ class TxDownloadTest(BitcoinTestFramework): wait_until(lambda: p.tx_getdata_count == MAX_GETDATA_IN_FLIGHT + 2) self.nodes[0].setmocktime(0) + def test_spurious_notfound(self): + self.log.info('Check that spurious notfound is ignored') + self.nodes[0].p2ps[0].send_message(msg_notfound(vec=[CInv(1, 1)])) + def run_test(self): # Setup the p2p connections self.peers = [] @@ -161,6 +165,8 @@ class TxDownloadTest(BitcoinTestFramework): self.log.info("Nodes are setup with {} incoming connections each".format(NUM_INBOUND)) + self.test_spurious_notfound() + # Test the in-flight max first, because we want no transactions in # flight ahead of this test. self.test_in_flight_max()