|
|
|
@ -378,18 +378,22 @@ class P2PInterface(P2PConnection):
|
|
|
|
|
|
|
|
|
|
# Connection helper methods
|
|
|
|
|
|
|
|
|
|
def wait_until(self, test_function, timeout=60):
|
|
|
|
|
def wait_until(self, test_function_in, *, timeout=60, check_connected=True):
|
|
|
|
|
def test_function():
|
|
|
|
|
if check_connected:
|
|
|
|
|
assert self.is_connected
|
|
|
|
|
return test_function_in()
|
|
|
|
|
|
|
|
|
|
wait_until(test_function, timeout=timeout, lock=mininode_lock, timeout_factor=self.timeout_factor)
|
|
|
|
|
|
|
|
|
|
def wait_for_disconnect(self, timeout=60):
|
|
|
|
|
test_function = lambda: not self.is_connected
|
|
|
|
|
self.wait_until(test_function, timeout=timeout)
|
|
|
|
|
self.wait_until(test_function, timeout=timeout, check_connected=False)
|
|
|
|
|
|
|
|
|
|
# Message receiving helper methods
|
|
|
|
|
|
|
|
|
|
def wait_for_tx(self, txid, timeout=60):
|
|
|
|
|
def test_function():
|
|
|
|
|
assert self.is_connected
|
|
|
|
|
if not self.last_message.get('tx'):
|
|
|
|
|
return False
|
|
|
|
|
return self.last_message['tx'].tx.rehash() == txid
|
|
|
|
@ -398,14 +402,12 @@ class P2PInterface(P2PConnection):
|
|
|
|
|
|
|
|
|
|
def wait_for_block(self, blockhash, timeout=60):
|
|
|
|
|
def test_function():
|
|
|
|
|
assert self.is_connected
|
|
|
|
|
return self.last_message.get("block") and self.last_message["block"].block.rehash() == blockhash
|
|
|
|
|
|
|
|
|
|
self.wait_until(test_function, timeout=timeout)
|
|
|
|
|
|
|
|
|
|
def wait_for_header(self, blockhash, timeout=60):
|
|
|
|
|
def test_function():
|
|
|
|
|
assert self.is_connected
|
|
|
|
|
last_headers = self.last_message.get('headers')
|
|
|
|
|
if not last_headers:
|
|
|
|
|
return False
|
|
|
|
@ -415,7 +417,6 @@ class P2PInterface(P2PConnection):
|
|
|
|
|
|
|
|
|
|
def wait_for_merkleblock(self, blockhash, timeout=60):
|
|
|
|
|
def test_function():
|
|
|
|
|
assert self.is_connected
|
|
|
|
|
last_filtered_block = self.last_message.get('merkleblock')
|
|
|
|
|
if not last_filtered_block:
|
|
|
|
|
return False
|
|
|
|
@ -427,9 +428,7 @@ class P2PInterface(P2PConnection):
|
|
|
|
|
"""Waits for a getdata message.
|
|
|
|
|
|
|
|
|
|
The object hashes in the inventory vector must match the provided hash_list."""
|
|
|
|
|
|
|
|
|
|
def test_function():
|
|
|
|
|
assert self.is_connected
|
|
|
|
|
last_data = self.last_message.get("getdata")
|
|
|
|
|
if not last_data:
|
|
|
|
|
return False
|
|
|
|
@ -444,9 +443,7 @@ class P2PInterface(P2PConnection):
|
|
|
|
|
value must be explicitly cleared before calling this method, or this will return
|
|
|
|
|
immediately with success. TODO: change this method to take a hash value and only
|
|
|
|
|
return true if the correct block header has been requested."""
|
|
|
|
|
|
|
|
|
|
def test_function():
|
|
|
|
|
assert self.is_connected
|
|
|
|
|
return self.last_message.get("getheaders")
|
|
|
|
|
|
|
|
|
|
self.wait_until(test_function, timeout=timeout)
|
|
|
|
@ -457,7 +454,6 @@ class P2PInterface(P2PConnection):
|
|
|
|
|
raise NotImplementedError("wait_for_inv() will only verify the first inv object")
|
|
|
|
|
|
|
|
|
|
def test_function():
|
|
|
|
|
assert self.is_connected
|
|
|
|
|
return self.last_message.get("inv") and \
|
|
|
|
|
self.last_message["inv"].inv[0].type == expected_inv[0].type and \
|
|
|
|
|
self.last_message["inv"].inv[0].hash == expected_inv[0].hash
|
|
|
|
@ -468,7 +464,7 @@ class P2PInterface(P2PConnection):
|
|
|
|
|
def test_function():
|
|
|
|
|
return self.message_count["verack"]
|
|
|
|
|
|
|
|
|
|
self.wait_until(test_function, timeout=timeout)
|
|
|
|
|
self.wait_until(test_function, timeout=timeout, check_connected=False)
|
|
|
|
|
|
|
|
|
|
# Message sending helper functions
|
|
|
|
|
|
|
|
|
@ -481,7 +477,6 @@ class P2PInterface(P2PConnection):
|
|
|
|
|
self.send_message(msg_ping(nonce=self.ping_counter))
|
|
|
|
|
|
|
|
|
|
def test_function():
|
|
|
|
|
assert self.is_connected
|
|
|
|
|
return self.last_message.get("pong") and self.last_message["pong"].nonce == self.ping_counter
|
|
|
|
|
|
|
|
|
|
self.wait_until(test_function, timeout=timeout)
|
|
|
|
@ -599,7 +594,11 @@ class P2PDataStore(P2PInterface):
|
|
|
|
|
self.send_message(msg_block(block=b))
|
|
|
|
|
else:
|
|
|
|
|
self.send_message(msg_headers([CBlockHeader(block) for block in blocks]))
|
|
|
|
|
self.wait_until(lambda: blocks[-1].sha256 in self.getdata_requests, timeout=timeout)
|
|
|
|
|
self.wait_until(
|
|
|
|
|
lambda: blocks[-1].sha256 in self.getdata_requests,
|
|
|
|
|
timeout=timeout,
|
|
|
|
|
check_connected=success,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if expect_disconnect:
|
|
|
|
|
self.wait_for_disconnect(timeout=timeout)
|
|
|
|
@ -667,6 +666,6 @@ class P2PTxInvStore(P2PInterface):
|
|
|
|
|
The mempool should mark unbroadcast=False for these transactions.
|
|
|
|
|
"""
|
|
|
|
|
# Wait until invs have been received (and getdatas sent) for each txid.
|
|
|
|
|
self.wait_until(lambda: set(self.tx_invs_received.keys()) == set([int(tx, 16) for tx in txns]), timeout)
|
|
|
|
|
self.wait_until(lambda: set(self.tx_invs_received.keys()) == set([int(tx, 16) for tx in txns]), timeout=timeout)
|
|
|
|
|
# Flush messages and wait for the getdatas to be processed
|
|
|
|
|
self.sync_with_ping()
|
|
|
|
|