diff options
Diffstat (limited to 'test/functional/p2p_filter.py')
-rwxr-xr-x | test/functional/p2p_filter.py | 54 |
1 files changed, 39 insertions, 15 deletions
diff --git a/test/functional/p2p_filter.py b/test/functional/p2p_filter.py index 188b130a57..a8b768c144 100755 --- a/test/functional/p2p_filter.py +++ b/test/functional/p2p_filter.py @@ -7,17 +7,18 @@ Test BIP 37 """ from test_framework.messages import ( + CInv, + MAX_BLOOM_FILTER_SIZE, + MAX_BLOOM_HASH_FUNCS, MSG_BLOCK, MSG_FILTERED_BLOCK, - msg_getdata, - msg_filterload, msg_filteradd, msg_filterclear, + msg_filterload, + msg_getdata, ) -from test_framework.mininode import ( - P2PInterface, - mininode_lock, -) +from test_framework.mininode import P2PInterface +from test_framework.script import MAX_SCRIPT_ELEMENT_SIZE from test_framework.test_framework import BitcoinTestFramework @@ -38,8 +39,9 @@ class FilterNode(P2PInterface): for i in message.inv: # inv messages can only contain TX or BLOCK, so translate BLOCK to FILTERED_BLOCK if i.type == MSG_BLOCK: - i.type = MSG_FILTERED_BLOCK - want.inv.append(i) + want.inv.append(CInv(MSG_FILTERED_BLOCK, i.hash)) + else: + want.inv.append(i) if len(want.inv): self.send_message(want) @@ -63,24 +65,32 @@ 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=MAX_BLOOM_HASH_FUNCS+1)) + with self.nodes[0].assert_debug_log(['Misbehaving']): + filter_node.send_and_ping(msg_filterload(data=b'\xbb'*(MAX_BLOOM_FILTER_SIZE+1))) + + self.log.info('Check that too large data element to add to the filter is rejected') + with self.nodes[0].assert_debug_log(['Misbehaving']): + filter_node.send_and_ping(msg_filteradd(data=b'\xcc'*(MAX_SCRIPT_ELEMENT_SIZE+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] self.log.info('Check that we receive merkleblock and tx if the filter matches a tx in a block') - filter_node.merkleblock_received = False block_hash = self.nodes[0].generatetoaddress(1, filter_address)[0] txid = self.nodes[0].getblock(block_hash)['tx'][0] + filter_node.wait_for_merkleblock(block_hash) filter_node.wait_for_tx(txid) - assert filter_node.merkleblock_received self.log.info('Check that we only receive a merkleblock if the filter does not match a tx in a block') - with mininode_lock: - filter_node.last_message.pop("merkleblock", None) filter_node.tx_received = False - self.nodes[0].generatetoaddress(1, self.nodes[0].getnewaddress()) - filter_node.wait_for_merkleblock() + block_hash = self.nodes[0].generatetoaddress(1, self.nodes[0].getnewaddress())[0] + filter_node.wait_for_merkleblock(block_hash) assert not filter_node.tx_received self.log.info('Check that we not receive a tx if the filter does not match a mempool tx') @@ -104,6 +114,20 @@ class FilterTest(BitcoinTestFramework): txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 7) filter_node.wait_for_tx(txid) + self.log.info('Check that request for filtered blocks is ignored if no filter is set') + filter_node.merkleblock_received = False + filter_node.tx_received = False + with self.nodes[0].assert_debug_log(expected_msgs=['received getdata']): + block_hash = self.nodes[0].generatetoaddress(1, self.nodes[0].getnewaddress())[0] + filter_node.wait_for_inv([CInv(MSG_BLOCK, int(block_hash, 16))]) + filter_node.sync_with_ping() + assert not filter_node.merkleblock_received + assert not filter_node.tx_received + + self.log.info('Check that sending "filteradd" if no filter is set is treated as misbehavior') + with self.nodes[0].assert_debug_log(['Misbehaving']): + filter_node.send_and_ping(msg_filteradd(data=b'letsmisbehave')) + self.log.info("Check that division-by-zero remote crash bug [CVE-2013-5700] is fixed") filter_node.send_and_ping(msg_filterload(data=b'', nHashFuncs=1)) filter_node.send_and_ping(msg_filteradd(data=b'letstrytocrashthisnode')) |