|
|
@ -70,7 +70,7 @@ class TestNode(NodeConnCB): |
|
|
|
def request_headers_and_sync(self, locator, hashstop=0): |
|
|
|
def request_headers_and_sync(self, locator, hashstop=0): |
|
|
|
self.clear_block_announcement() |
|
|
|
self.clear_block_announcement() |
|
|
|
self.get_headers(locator, hashstop) |
|
|
|
self.get_headers(locator, hashstop) |
|
|
|
assert wait_until(self.received_block_announcement, timeout=30) |
|
|
|
wait_until(self.received_block_announcement, timeout=30, lock=mininode_lock) |
|
|
|
self.clear_block_announcement() |
|
|
|
self.clear_block_announcement() |
|
|
|
|
|
|
|
|
|
|
|
# Block until a block announcement for a particular block hash is |
|
|
|
# Block until a block announcement for a particular block hash is |
|
|
@ -78,7 +78,7 @@ class TestNode(NodeConnCB): |
|
|
|
def wait_for_block_announcement(self, block_hash, timeout=30): |
|
|
|
def wait_for_block_announcement(self, block_hash, timeout=30): |
|
|
|
def received_hash(): |
|
|
|
def received_hash(): |
|
|
|
return (block_hash in self.announced_blockhashes) |
|
|
|
return (block_hash in self.announced_blockhashes) |
|
|
|
return wait_until(received_hash, timeout=timeout) |
|
|
|
wait_until(received_hash, timeout=timeout, lock=mininode_lock) |
|
|
|
|
|
|
|
|
|
|
|
def send_await_disconnect(self, message, timeout=30): |
|
|
|
def send_await_disconnect(self, message, timeout=30): |
|
|
|
"""Sends a message to the node and wait for disconnect. |
|
|
|
"""Sends a message to the node and wait for disconnect. |
|
|
@ -86,11 +86,7 @@ class TestNode(NodeConnCB): |
|
|
|
This is used when we want to send a message into the node that we expect |
|
|
|
This is used when we want to send a message into the node that we expect |
|
|
|
will get us disconnected, eg an invalid block.""" |
|
|
|
will get us disconnected, eg an invalid block.""" |
|
|
|
self.send_message(message) |
|
|
|
self.send_message(message) |
|
|
|
success = wait_until(lambda: not self.connected, timeout=timeout) |
|
|
|
wait_until(lambda: not self.connected, timeout=timeout, lock=mininode_lock) |
|
|
|
if not success: |
|
|
|
|
|
|
|
logger.error("send_await_disconnect failed!") |
|
|
|
|
|
|
|
raise AssertionError("send_await_disconnect failed!") |
|
|
|
|
|
|
|
return success |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CompactBlocksTest(BitcoinTestFramework): |
|
|
|
class CompactBlocksTest(BitcoinTestFramework): |
|
|
|
def __init__(self): |
|
|
|
def __init__(self): |
|
|
@ -150,9 +146,7 @@ class CompactBlocksTest(BitcoinTestFramework): |
|
|
|
# Make sure we get a SENDCMPCT message from our peer |
|
|
|
# Make sure we get a SENDCMPCT message from our peer |
|
|
|
def received_sendcmpct(): |
|
|
|
def received_sendcmpct(): |
|
|
|
return (len(test_node.last_sendcmpct) > 0) |
|
|
|
return (len(test_node.last_sendcmpct) > 0) |
|
|
|
got_message = wait_until(received_sendcmpct, timeout=30) |
|
|
|
wait_until(received_sendcmpct, timeout=30, lock=mininode_lock) |
|
|
|
assert(received_sendcmpct()) |
|
|
|
|
|
|
|
assert(got_message) |
|
|
|
|
|
|
|
with mininode_lock: |
|
|
|
with mininode_lock: |
|
|
|
# Check that the first version received is the preferred one |
|
|
|
# Check that the first version received is the preferred one |
|
|
|
assert_equal(test_node.last_sendcmpct[0].version, preferred_version) |
|
|
|
assert_equal(test_node.last_sendcmpct[0].version, preferred_version) |
|
|
@ -167,7 +161,6 @@ class CompactBlocksTest(BitcoinTestFramework): |
|
|
|
block_hash = int(node.generate(1)[0], 16) |
|
|
|
block_hash = int(node.generate(1)[0], 16) |
|
|
|
peer.wait_for_block_announcement(block_hash, timeout=30) |
|
|
|
peer.wait_for_block_announcement(block_hash, timeout=30) |
|
|
|
assert(peer.block_announced) |
|
|
|
assert(peer.block_announced) |
|
|
|
assert(got_message) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
with mininode_lock: |
|
|
|
with mininode_lock: |
|
|
|
assert predicate(peer), ( |
|
|
|
assert predicate(peer), ( |
|
|
@ -282,7 +275,7 @@ class CompactBlocksTest(BitcoinTestFramework): |
|
|
|
|
|
|
|
|
|
|
|
# Wait until we've seen the block announcement for the resulting tip |
|
|
|
# Wait until we've seen the block announcement for the resulting tip |
|
|
|
tip = int(node.getbestblockhash(), 16) |
|
|
|
tip = int(node.getbestblockhash(), 16) |
|
|
|
assert(test_node.wait_for_block_announcement(tip)) |
|
|
|
test_node.wait_for_block_announcement(tip) |
|
|
|
|
|
|
|
|
|
|
|
# Make sure we will receive a fast-announce compact block |
|
|
|
# Make sure we will receive a fast-announce compact block |
|
|
|
self.request_cb_announcements(test_node, node, version) |
|
|
|
self.request_cb_announcements(test_node, node, version) |
|
|
@ -297,8 +290,7 @@ class CompactBlocksTest(BitcoinTestFramework): |
|
|
|
block.rehash() |
|
|
|
block.rehash() |
|
|
|
|
|
|
|
|
|
|
|
# Wait until the block was announced (via compact blocks) |
|
|
|
# Wait until the block was announced (via compact blocks) |
|
|
|
wait_until(test_node.received_block_announcement, timeout=30) |
|
|
|
wait_until(test_node.received_block_announcement, timeout=30, lock=mininode_lock) |
|
|
|
assert(test_node.received_block_announcement()) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Now fetch and check the compact block |
|
|
|
# Now fetch and check the compact block |
|
|
|
header_and_shortids = None |
|
|
|
header_and_shortids = None |
|
|
@ -314,8 +306,7 @@ class CompactBlocksTest(BitcoinTestFramework): |
|
|
|
inv = CInv(4, block_hash) # 4 == "CompactBlock" |
|
|
|
inv = CInv(4, block_hash) # 4 == "CompactBlock" |
|
|
|
test_node.send_message(msg_getdata([inv])) |
|
|
|
test_node.send_message(msg_getdata([inv])) |
|
|
|
|
|
|
|
|
|
|
|
wait_until(test_node.received_block_announcement, timeout=30) |
|
|
|
wait_until(test_node.received_block_announcement, timeout=30, lock=mininode_lock) |
|
|
|
assert(test_node.received_block_announcement()) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Now fetch and check the compact block |
|
|
|
# Now fetch and check the compact block |
|
|
|
header_and_shortids = None |
|
|
|
header_and_shortids = None |
|
|
@ -386,13 +377,11 @@ class CompactBlocksTest(BitcoinTestFramework): |
|
|
|
|
|
|
|
|
|
|
|
if announce == "inv": |
|
|
|
if announce == "inv": |
|
|
|
test_node.send_message(msg_inv([CInv(2, block.sha256)])) |
|
|
|
test_node.send_message(msg_inv([CInv(2, block.sha256)])) |
|
|
|
success = wait_until(lambda: "getheaders" in test_node.last_message, timeout=30) |
|
|
|
wait_until(lambda: "getheaders" in test_node.last_message, timeout=30, lock=mininode_lock) |
|
|
|
assert(success) |
|
|
|
|
|
|
|
test_node.send_header_for_blocks([block]) |
|
|
|
test_node.send_header_for_blocks([block]) |
|
|
|
else: |
|
|
|
else: |
|
|
|
test_node.send_header_for_blocks([block]) |
|
|
|
test_node.send_header_for_blocks([block]) |
|
|
|
success = wait_until(lambda: "getdata" in test_node.last_message, timeout=30) |
|
|
|
wait_until(lambda: "getdata" in test_node.last_message, timeout=30, lock=mininode_lock) |
|
|
|
assert(success) |
|
|
|
|
|
|
|
assert_equal(len(test_node.last_message["getdata"].inv), 1) |
|
|
|
assert_equal(len(test_node.last_message["getdata"].inv), 1) |
|
|
|
assert_equal(test_node.last_message["getdata"].inv[0].type, 4) |
|
|
|
assert_equal(test_node.last_message["getdata"].inv[0].type, 4) |
|
|
|
assert_equal(test_node.last_message["getdata"].inv[0].hash, block.sha256) |
|
|
|
assert_equal(test_node.last_message["getdata"].inv[0].hash, block.sha256) |
|
|
@ -571,8 +560,7 @@ class CompactBlocksTest(BitcoinTestFramework): |
|
|
|
assert_equal(int(node.getbestblockhash(), 16), block.hashPrevBlock) |
|
|
|
assert_equal(int(node.getbestblockhash(), 16), block.hashPrevBlock) |
|
|
|
|
|
|
|
|
|
|
|
# We should receive a getdata request |
|
|
|
# We should receive a getdata request |
|
|
|
success = wait_until(lambda: "getdata" in test_node.last_message, timeout=10) |
|
|
|
wait_until(lambda: "getdata" in test_node.last_message, timeout=10, lock=mininode_lock) |
|
|
|
assert(success) |
|
|
|
|
|
|
|
assert_equal(len(test_node.last_message["getdata"].inv), 1) |
|
|
|
assert_equal(len(test_node.last_message["getdata"].inv), 1) |
|
|
|
assert(test_node.last_message["getdata"].inv[0].type == 2 or test_node.last_message["getdata"].inv[0].type == 2|MSG_WITNESS_FLAG) |
|
|
|
assert(test_node.last_message["getdata"].inv[0].type == 2 or test_node.last_message["getdata"].inv[0].type == 2|MSG_WITNESS_FLAG) |
|
|
|
assert_equal(test_node.last_message["getdata"].inv[0].hash, block.sha256) |
|
|
|
assert_equal(test_node.last_message["getdata"].inv[0].hash, block.sha256) |
|
|
@ -599,8 +587,7 @@ class CompactBlocksTest(BitcoinTestFramework): |
|
|
|
num_to_request = random.randint(1, len(block.vtx)) |
|
|
|
num_to_request = random.randint(1, len(block.vtx)) |
|
|
|
msg.block_txn_request.from_absolute(sorted(random.sample(range(len(block.vtx)), num_to_request))) |
|
|
|
msg.block_txn_request.from_absolute(sorted(random.sample(range(len(block.vtx)), num_to_request))) |
|
|
|
test_node.send_message(msg) |
|
|
|
test_node.send_message(msg) |
|
|
|
success = wait_until(lambda: "blocktxn" in test_node.last_message, timeout=10) |
|
|
|
wait_until(lambda: "blocktxn" in test_node.last_message, timeout=10, lock=mininode_lock) |
|
|
|
assert(success) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[tx.calc_sha256() for tx in block.vtx] |
|
|
|
[tx.calc_sha256() for tx in block.vtx] |
|
|
|
with mininode_lock: |
|
|
|
with mininode_lock: |
|
|
@ -639,22 +626,20 @@ class CompactBlocksTest(BitcoinTestFramework): |
|
|
|
for i in range(MAX_CMPCTBLOCK_DEPTH + 1): |
|
|
|
for i in range(MAX_CMPCTBLOCK_DEPTH + 1): |
|
|
|
test_node.clear_block_announcement() |
|
|
|
test_node.clear_block_announcement() |
|
|
|
new_blocks.append(node.generate(1)[0]) |
|
|
|
new_blocks.append(node.generate(1)[0]) |
|
|
|
wait_until(test_node.received_block_announcement, timeout=30) |
|
|
|
wait_until(test_node.received_block_announcement, timeout=30, lock=mininode_lock) |
|
|
|
|
|
|
|
|
|
|
|
test_node.clear_block_announcement() |
|
|
|
test_node.clear_block_announcement() |
|
|
|
test_node.send_message(msg_getdata([CInv(4, int(new_blocks[0], 16))])) |
|
|
|
test_node.send_message(msg_getdata([CInv(4, int(new_blocks[0], 16))])) |
|
|
|
success = wait_until(lambda: "cmpctblock" in test_node.last_message, timeout=30) |
|
|
|
wait_until(lambda: "cmpctblock" in test_node.last_message, timeout=30, lock=mininode_lock) |
|
|
|
assert(success) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
test_node.clear_block_announcement() |
|
|
|
test_node.clear_block_announcement() |
|
|
|
node.generate(1) |
|
|
|
node.generate(1) |
|
|
|
wait_until(test_node.received_block_announcement, timeout=30) |
|
|
|
wait_until(test_node.received_block_announcement, timeout=30, lock=mininode_lock) |
|
|
|
test_node.clear_block_announcement() |
|
|
|
test_node.clear_block_announcement() |
|
|
|
with mininode_lock: |
|
|
|
with mininode_lock: |
|
|
|
test_node.last_message.pop("block", None) |
|
|
|
test_node.last_message.pop("block", None) |
|
|
|
test_node.send_message(msg_getdata([CInv(4, int(new_blocks[0], 16))])) |
|
|
|
test_node.send_message(msg_getdata([CInv(4, int(new_blocks[0], 16))])) |
|
|
|
success = wait_until(lambda: "block" in test_node.last_message, timeout=30) |
|
|
|
wait_until(lambda: "block" in test_node.last_message, timeout=30, lock=mininode_lock) |
|
|
|
assert(success) |
|
|
|
|
|
|
|
with mininode_lock: |
|
|
|
with mininode_lock: |
|
|
|
test_node.last_message["block"].block.calc_sha256() |
|
|
|
test_node.last_message["block"].block.calc_sha256() |
|
|
|
assert_equal(test_node.last_message["block"].block.sha256, int(new_blocks[0], 16)) |
|
|
|
assert_equal(test_node.last_message["block"].block.sha256, int(new_blocks[0], 16)) |
|
|
@ -705,7 +690,7 @@ class CompactBlocksTest(BitcoinTestFramework): |
|
|
|
node.submitblock(ToHex(block)) |
|
|
|
node.submitblock(ToHex(block)) |
|
|
|
|
|
|
|
|
|
|
|
for l in listeners: |
|
|
|
for l in listeners: |
|
|
|
wait_until(lambda: l.received_block_announcement(), timeout=30) |
|
|
|
wait_until(lambda: l.received_block_announcement(), timeout=30, lock=mininode_lock) |
|
|
|
with mininode_lock: |
|
|
|
with mininode_lock: |
|
|
|
for l in listeners: |
|
|
|
for l in listeners: |
|
|
|
assert "cmpctblock" in l.last_message |
|
|
|
assert "cmpctblock" in l.last_message |
|
|
|