Changeset View
Changeset View
Standalone View
Standalone View
test/functional/feature_block.py
Show First 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | class FullBlockTest(BitcoinTestFramework): | ||||
def set_test_params(self): | def set_test_params(self): | ||||
self.num_nodes = 1 | self.num_nodes = 1 | ||||
self.setup_clean_chain = True | self.setup_clean_chain = True | ||||
self.extra_args = [['-noparkdeepreorg', '-maxreorgdepth=-1']] | self.extra_args = [['-noparkdeepreorg', '-maxreorgdepth=-1']] | ||||
def run_test(self): | def run_test(self): | ||||
node = self.nodes[0] # convenience reference to the node | node = self.nodes[0] # convenience reference to the node | ||||
# reconnect_p2p() expects the network thread to be running | self.bootstrap_p2p() # Add one p2p connection to the node | ||||
network_thread_start() | |||||
self.reconnect_p2p() | |||||
self.block_heights = {} | self.block_heights = {} | ||||
self.coinbase_key = CECKey() | self.coinbase_key = CECKey() | ||||
self.coinbase_key.set_secretbytes(b"horsebattery") | self.coinbase_key.set_secretbytes(b"horsebattery") | ||||
self.coinbase_pubkey = self.coinbase_key.get_pubkey() | self.coinbase_pubkey = self.coinbase_key.get_pubkey() | ||||
self.tip = None | self.tip = None | ||||
self.blocks = {} | self.blocks = {} | ||||
self.genesis_hash = int(self.nodes[0].getbestblockhash(), 16) | self.genesis_hash = int(self.nodes[0].getbestblockhash(), 16) | ||||
▲ Show 20 Lines • Show All 1,266 Lines • ▼ Show 20 Lines | def update_block(self, block_number, new_transactions, reorder=True): | ||||
# Update the internal state just like in next_block | # Update the internal state just like in next_block | ||||
self.tip = block | self.tip = block | ||||
if block.sha256 != old_sha256: | if block.sha256 != old_sha256: | ||||
self.block_heights[block.sha256] = self.block_heights[old_sha256] | self.block_heights[block.sha256] = self.block_heights[old_sha256] | ||||
del self.block_heights[old_sha256] | del self.block_heights[old_sha256] | ||||
self.blocks[block_number] = block | self.blocks[block_number] = block | ||||
return block | return block | ||||
def reconnect_p2p(self): | def bootstrap_p2p(self): | ||||
"""Add a P2P connection to the node. | """Add a P2P connection to the node. | ||||
The node gets disconnected several times in this test. This helper | Helper to connect and wait for version handshake.""" | ||||
method reconnects the p2p and restarts the network thread.""" | |||||
network_thread_join() | |||||
self.nodes[0].disconnect_p2ps() | |||||
self.nodes[0].add_p2p_connection(P2PDataStore()) | self.nodes[0].add_p2p_connection(P2PDataStore()) | ||||
network_thread_start() | network_thread_start() | ||||
# We need to wait for the initial getheaders from the peer before we | # We need to wait for the initial getheaders from the peer before we | ||||
# start populating our blockstore. If we don't, then we may run ahead | # start populating our blockstore. If we don't, then we may run ahead | ||||
# to the next subtest before we receive the getheaders. We'd then send | # to the next subtest before we receive the getheaders. We'd then send | ||||
# an INV for the next block and receive two getheaders - one for the | # an INV for the next block and receive two getheaders - one for the | ||||
# IBD and one for the INV. We'd respond to both and could get | # IBD and one for the INV. We'd respond to both and could get | ||||
# unexpectedly disconnected if the DoS score for that error is 50. | # unexpectedly disconnected if the DoS score for that error is 50. | ||||
self.nodes[0].p2p.wait_for_getheaders(timeout=5) | self.nodes[0].p2p.wait_for_getheaders(timeout=5) | ||||
def reconnect_p2p(self): | |||||
"""Tear down and bootstrap the P2P connection to the node. | |||||
The node gets disconnected several times in this test. This helper | |||||
method reconnects the p2p and restarts the network thread.""" | |||||
self.nodes[0].disconnect_p2ps() | |||||
network_thread_join() | |||||
self.bootstrap_p2p() | |||||
def sync_blocks(self, blocks, success=True, reject_code=None, reject_reason=None, request_block=True, reconnect=False, timeout=60): | def sync_blocks(self, blocks, success=True, reject_code=None, reject_reason=None, request_block=True, reconnect=False, timeout=60): | ||||
"""Sends blocks to test node. Syncs and verifies that tip has advanced to most recent block. | """Sends blocks to test node. Syncs and verifies that tip has advanced to most recent block. | ||||
Call with success = False if the tip shouldn't advance to the most recent block.""" | Call with success = False if the tip shouldn't advance to the most recent block.""" | ||||
self.nodes[0].p2p.send_blocks_and_test(blocks, self.nodes[0], success=success, reject_code=reject_code, | self.nodes[0].p2p.send_blocks_and_test(blocks, self.nodes[0], success=success, reject_code=reject_code, | ||||
reject_reason=reject_reason, request_block=request_block, timeout=timeout) | reject_reason=reject_reason, request_block=request_block, timeout=timeout) | ||||
if reconnect: | if reconnect: | ||||
self.reconnect_p2p() | self.reconnect_p2p() | ||||
if __name__ == '__main__': | if __name__ == '__main__': | ||||
FullBlockTest().main() | FullBlockTest().main() |