aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xtest/functional/p2p_segwit.py10
-rwxr-xr-xtest/functional/p2p_tx_download.py53
-rwxr-xr-xtest/functional/test_framework/p2p.py7
3 files changed, 44 insertions, 26 deletions
diff --git a/test/functional/p2p_segwit.py b/test/functional/p2p_segwit.py
index e99ecd8026..a9d8b12d70 100755
--- a/test/functional/p2p_segwit.py
+++ b/test/functional/p2p_segwit.py
@@ -37,7 +37,6 @@ from test_framework.messages import (
msg_tx,
msg_block,
msg_no_witness_tx,
- msg_verack,
ser_uint256,
ser_vector,
sha256,
@@ -146,7 +145,7 @@ def test_witness_block(node, p2p, block, accepted, with_witness=True, reason=Non
class TestP2PConn(P2PInterface):
def __init__(self, wtxidrelay=False):
- super().__init__()
+ super().__init__(wtxidrelay=wtxidrelay)
self.getdataset = set()
self.last_wtxidrelay = []
self.lastgetdata = []
@@ -157,13 +156,6 @@ class TestP2PConn(P2PInterface):
def on_inv(self, message):
pass
- def on_version(self, message):
- if self.wtxidrelay:
- super().on_version(message)
- else:
- self.send_message(msg_verack())
- self.nServices = message.nServices
-
def on_getdata(self, message):
self.lastgetdata = message.inv
for inv in message.inv:
diff --git a/test/functional/p2p_tx_download.py b/test/functional/p2p_tx_download.py
index 16d9302db8..8a751c6b54 100755
--- a/test/functional/p2p_tx_download.py
+++ b/test/functional/p2p_tx_download.py
@@ -30,8 +30,8 @@ import time
class TestP2PConn(P2PInterface):
- def __init__(self):
- super().__init__()
+ def __init__(self, wtxidrelay=True):
+ super().__init__(wtxidrelay=wtxidrelay)
self.tx_getdata_count = 0
def on_getdata(self, message):
@@ -47,6 +47,7 @@ TXID_RELAY_DELAY = 2 # seconds
OVERLOADED_PEER_DELAY = 2 # seconds
MAX_GETDATA_IN_FLIGHT = 100
MAX_PEER_TX_ANNOUNCEMENTS = 5000
+NONPREF_PEER_TX_DELAY = 2
# Python test constants
NUM_INBOUND = 10
@@ -168,8 +169,6 @@ class TxDownloadTest(BitcoinTestFramework):
assert_equal(peer_fallback.tx_getdata_count, 0)
self.nodes[0].setmocktime(int(time.time()) + GETDATA_TX_INTERVAL + 1) # Wait for request to peer_expiry to expire
peer_fallback.wait_until(lambda: peer_fallback.tx_getdata_count >= 1, timeout=1)
- with p2p_lock:
- assert_equal(peer_fallback.tx_getdata_count, 1)
self.restart_node(0) # reset mocktime
def test_disconnect_fallback(self):
@@ -187,8 +186,6 @@ class TxDownloadTest(BitcoinTestFramework):
peer_disconnect.peer_disconnect()
peer_disconnect.wait_for_disconnect()
peer_fallback.wait_until(lambda: peer_fallback.tx_getdata_count >= 1, timeout=1)
- with p2p_lock:
- assert_equal(peer_fallback.tx_getdata_count, 1)
def test_notfound_fallback(self):
self.log.info('Check that notfounds will select another peer for download immediately')
@@ -204,17 +201,42 @@ class TxDownloadTest(BitcoinTestFramework):
assert_equal(peer_fallback.tx_getdata_count, 0)
peer_notfound.send_and_ping(msg_notfound(vec=[CInv(MSG_WTX, WTXID)])) # Send notfound, so that fallback peer is selected
peer_fallback.wait_until(lambda: peer_fallback.tx_getdata_count >= 1, timeout=1)
- with p2p_lock:
- assert_equal(peer_fallback.tx_getdata_count, 1)
- def test_preferred_inv(self):
- self.log.info('Check that invs from preferred peers are downloaded immediately')
- self.restart_node(0, extra_args=['-whitelist=noban@127.0.0.1'])
+ def test_preferred_inv(self, preferred=False):
+ if preferred:
+ self.log.info('Check invs from preferred peers are downloaded immediately')
+ self.restart_node(0, extra_args=['-whitelist=noban@127.0.0.1'])
+ else:
+ self.log.info('Check invs from non-preferred peers are downloaded after {} s'.format(NONPREF_PEER_TX_DELAY))
+ mock_time = int(time.time() + 1)
+ self.nodes[0].setmocktime(mock_time)
peer = self.nodes[0].add_p2p_connection(TestP2PConn())
peer.send_message(msg_inv([CInv(t=MSG_WTX, h=0xff00ff00)]))
- peer.wait_until(lambda: peer.tx_getdata_count >= 1, timeout=1)
+ peer.sync_with_ping()
+ if preferred:
+ peer.wait_until(lambda: peer.tx_getdata_count >= 1, timeout=1)
+ else:
+ with p2p_lock:
+ assert_equal(peer.tx_getdata_count, 0)
+ self.nodes[0].setmocktime(mock_time + NONPREF_PEER_TX_DELAY)
+ peer.wait_until(lambda: peer.tx_getdata_count >= 1, timeout=1)
+
+ def test_txid_inv_delay(self, glob_wtxid=False):
+ self.log.info('Check that inv from a txid-relay peers are delayed by {} s, with a wtxid peer {}'.format(TXID_RELAY_DELAY, glob_wtxid))
+ self.restart_node(0, extra_args=['-whitelist=noban@127.0.0.1'])
+ mock_time = int(time.time() + 1)
+ self.nodes[0].setmocktime(mock_time)
+ peer = self.nodes[0].add_p2p_connection(TestP2PConn(wtxidrelay=False))
+ if glob_wtxid:
+ # Add a second wtxid-relay connection otherwise TXID_RELAY_DELAY is waived in
+ # lack of wtxid-relay peers
+ self.nodes[0].add_p2p_connection(TestP2PConn(wtxidrelay=True))
+ peer.send_message(msg_inv([CInv(t=MSG_TX, h=0xff11ff11)]))
+ peer.sync_with_ping()
with p2p_lock:
- assert_equal(peer.tx_getdata_count, 1)
+ assert_equal(peer.tx_getdata_count, 0 if glob_wtxid else 1)
+ self.nodes[0].setmocktime(mock_time + TXID_RELAY_DELAY)
+ peer.wait_until(lambda: peer.tx_getdata_count >= 1, timeout=1)
def test_large_inv_batch(self):
self.log.info('Test how large inv batches are handled with relay permission')
@@ -229,8 +251,6 @@ class TxDownloadTest(BitcoinTestFramework):
peer.send_message(msg_inv([CInv(t=MSG_WTX, h=wtxid) for wtxid in range(MAX_PEER_TX_ANNOUNCEMENTS + 1)]))
peer.wait_until(lambda: peer.tx_getdata_count == MAX_PEER_TX_ANNOUNCEMENTS)
peer.sync_with_ping()
- with p2p_lock:
- assert_equal(peer.tx_getdata_count, MAX_PEER_TX_ANNOUNCEMENTS)
def test_spurious_notfound(self):
self.log.info('Check that spurious notfound is ignored')
@@ -242,6 +262,9 @@ class TxDownloadTest(BitcoinTestFramework):
self.test_disconnect_fallback()
self.test_notfound_fallback()
self.test_preferred_inv()
+ self.test_preferred_inv(True)
+ self.test_txid_inv_delay()
+ self.test_txid_inv_delay(True)
self.test_large_inv_batch()
self.test_spurious_notfound()
diff --git a/test/functional/test_framework/p2p.py b/test/functional/test_framework/p2p.py
index 8b79a4dc2f..ea769ddfa2 100755
--- a/test/functional/test_framework/p2p.py
+++ b/test/functional/test_framework/p2p.py
@@ -289,7 +289,7 @@ class P2PInterface(P2PConnection):
Individual testcases should subclass this and override the on_* methods
if they want to alter message handling behaviour."""
- def __init__(self, support_addrv2=False):
+ def __init__(self, support_addrv2=False, wtxidrelay=True):
super().__init__()
# Track number of messages of each type received.
@@ -309,6 +309,9 @@ class P2PInterface(P2PConnection):
self.support_addrv2 = support_addrv2
+ # If the peer supports wtxid-relay
+ self.wtxidrelay = wtxidrelay
+
def peer_connect(self, *args, services=NODE_NETWORK|NODE_WITNESS, send_version=True, **kwargs):
create_conn = super().peer_connect(*args, **kwargs)
@@ -394,7 +397,7 @@ class P2PInterface(P2PConnection):
def on_version(self, message):
assert message.nVersion >= MIN_VERSION_SUPPORTED, "Version {} received. Test framework only supports versions greater than {}".format(message.nVersion, MIN_VERSION_SUPPORTED)
- if message.nVersion >= 70016:
+ if message.nVersion >= 70016 and self.wtxidrelay:
self.send_message(msg_wtxidrelay())
if self.support_addrv2:
self.send_message(msg_sendaddrv2())