aboutsummaryrefslogtreecommitdiff
path: root/test/functional/p2p_filter.py
diff options
context:
space:
mode:
authorMarcoFalke <falke.marco@gmail.com>2020-03-12 13:36:46 -0400
committerMarcoFalke <falke.marco@gmail.com>2020-03-25 06:45:43 -0400
commitfa156999695ddaeb016d8320bee62f8d96679d55 (patch)
tree1bae058d0c4e08422ec41392c063c677158dfb06 /test/functional/p2p_filter.py
parent2737197ff39f98b0fbdf0fe913c1a7c8ee0f318c (diff)
downloadbitcoin-fa156999695ddaeb016d8320bee62f8d96679d55.tar.xz
test: Add basic test for BIP 37
Diffstat (limited to 'test/functional/p2p_filter.py')
-rwxr-xr-xtest/functional/p2p_filter.py102
1 files changed, 102 insertions, 0 deletions
diff --git a/test/functional/p2p_filter.py b/test/functional/p2p_filter.py
new file mode 100755
index 0000000000..a22ee91483
--- /dev/null
+++ b/test/functional/p2p_filter.py
@@ -0,0 +1,102 @@
+#!/usr/bin/env python3
+# Copyright (c) 2020 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+"""
+Test BIP 37
+"""
+
+from test_framework.messages import (
+ MSG_BLOCK,
+ MSG_FILTERED_BLOCK,
+ msg_getdata,
+ msg_filterload,
+)
+from test_framework.mininode import (
+ P2PInterface,
+ mininode_lock,
+)
+from test_framework.test_framework import BitcoinTestFramework
+
+
+class FilterNode(P2PInterface):
+ # This is a P2SH watch-only wallet
+ watch_script_pubkey = 'a914ffffffffffffffffffffffffffffffffffffffff87'
+ # The initial filter (n=10, fp=0.000001) with just the above scriptPubKey added
+ watch_filter_init = msg_filterload(
+ data=
+ b'@\x00\x08\x00\x80\x00\x00 \x00\xc0\x00 \x04\x00\x08$\x00\x04\x80\x00\x00 \x00\x00\x00\x00\x80\x00\x00@\x00\x02@ \x00',
+ nHashFuncs=19,
+ nTweak=0,
+ nFlags=1,
+ )
+
+ def on_inv(self, message):
+ want = msg_getdata()
+ 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)
+ if len(want.inv):
+ self.send_message(want)
+
+ def on_merkleblock(self, message):
+ self.merkleblock_received = True
+
+ def on_tx(self, message):
+ self.tx_received = True
+
+
+class FilterTest(BitcoinTestFramework):
+ def set_test_params(self):
+ self.setup_clean_chain = False
+ self.num_nodes = 1
+ self.extra_args = [[
+ '-peerbloomfilters',
+ '-whitelist=noban@127.0.0.1', # immediate tx relay
+ ]]
+
+ def skip_test_if_missing_module(self):
+ 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())
+ filter_node.send_message(filter_node.watch_filter_init)
+ filter_node.sync_with_ping()
+ 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_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()
+ 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')
+ filter_node.merkleblock_received = False
+ filter_node.tx_received = False
+ self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 90)
+ filter_node.sync_with_ping()
+ filter_node.sync_with_ping()
+ assert not filter_node.merkleblock_received
+ assert not filter_node.tx_received
+
+ self.log.info('Check that we receive a tx in reply to a mempool msg if the filter matches a mempool tx')
+ filter_node.merkleblock_received = False
+ txid = self.nodes[0].sendtoaddress(filter_address, 90)
+ filter_node.wait_for_tx(txid)
+ assert not filter_node.merkleblock_received
+
+
+if __name__ == '__main__':
+ FilterTest().main()