def test_waiting_confirmation_timeout(self): block_hash_1 = Sha256Hash(helpers.generate_hash()) block_msg_1 = helpers.create_block_message(block_hash_1) block_hash_2 = Sha256Hash(helpers.generate_hash()) block_msg_2 = helpers.create_block_message(block_hash_2, block_hash_1) # first block gets sent immediately self.node.block_queuing_service_manager.push(block_hash_1, block_msg_1) self.node.block_queuing_service_manager.push(block_hash_2, block_msg_2) self._assert_length_of_enqueued_messages(1) self._assert_block_in_enqueued_messages_index(block_msg_1, 0) self._assert_len_of_block_queuing_services(1) self._assert_block_in_queuing_services(block_hash_1) self._assert_block_in_queuing_services(block_hash_2) time.time = MagicMock( return_value=time.time() + gateway_constants.MAX_INTERVAL_BETWEEN_BLOCKS_S ) self.node.alarm_queue.fire_alarms() self._assert_length_of_enqueued_messages(2) self._assert_block_in_enqueued_messages_index(block_msg_2, 1) self._assert_len_of_block_queuing_services(0) self._assert_block_in_queuing_services(block_hash_1) self._assert_block_in_queuing_services(block_hash_2)
def test_block_added_waiting_for_previous_block_confirmation(self): block_hash_1 = Sha256Hash(helpers.generate_hash()) block_msg_1 = create_block_message(block_hash_1) block_hash_2 = Sha256Hash(helpers.generate_hash()) block_msg_2 = create_block_message(block_hash_2, block_hash_1) # first block gets sent immediately self.block_queuing_service.push(block_hash_1, block_msg_1) self.assertEqual(1, len(self.node.broadcast_to_nodes_messages)) self.assertEqual(block_msg_1, self.node.broadcast_to_nodes_messages[0]) self.assertEqual(0, len(self.block_queuing_service)) self.assertIn(block_hash_1, self.block_queuing_service) # no confirmation, wait on block 1 self.block_queuing_service.push(block_hash_2, block_msg_2) self.assertEqual(1, len(self.node.broadcast_to_nodes_messages)) self.assertEqual(block_msg_1, self.node.broadcast_to_nodes_messages[0]) self.assertEqual(1, len(self.block_queuing_service)) self.assertIn(block_hash_1, self.block_queuing_service) self.assertIn(block_hash_2, self.block_queuing_service) self.block_queuing_service.mark_blocks_seen_by_blockchain_node( [block_hash_1]) self.assertEqual(2, len(self.node.broadcast_to_nodes_messages)) self.assertEqual(block_msg_2, self.node.broadcast_to_nodes_messages[1]) self.assertEqual(0, len(self.block_queuing_service))
def test_waiting_confirmation_timeout(self): block_hash_1 = Sha256Hash(helpers.generate_hash()) block_msg_1 = create_block_message(block_hash_1) block_hash_2 = Sha256Hash(helpers.generate_hash()) block_msg_2 = create_block_message(block_hash_2, block_hash_1) # first block gets sent immediately self.block_queuing_service.push(block_hash_1, block_msg_1) self.block_queuing_service.push(block_hash_2, block_msg_2) self.assertEqual(1, len(self.node.broadcast_to_nodes_messages)) self.assertEqual(block_msg_1, self.node.broadcast_to_nodes_messages[0]) self.assertEqual(1, len(self.block_queuing_service)) self.assertIn(block_hash_1, self.block_queuing_service) self.assertIn(block_hash_2, self.block_queuing_service) time.time = MagicMock(return_value=time.time() + gateway_constants.MAX_INTERVAL_BETWEEN_BLOCKS_S) self.node.alarm_queue.fire_alarms() self.assertEqual(2, len(self.node.broadcast_to_nodes_messages)) self.assertEqual(block_msg_2, self.node.broadcast_to_nodes_messages[1]) self.assertEqual(0, len(self.block_queuing_service)) self.assertIn(block_hash_1, self.block_queuing_service) self.assertIn(block_hash_2, self.block_queuing_service)
def test_broadcast_to_connection_type(self): relay_all_conn = self._add_connection(0, 9000, ALL_NETWORK_NUM, ConnectionType.RELAY_ALL) relay_block_conn = self._add_connection(1, 9001, ALL_NETWORK_NUM, ConnectionType.RELAY_BLOCK) relay_transaction_conn = self._add_connection(2, 9002, ALL_NETWORK_NUM, ConnectionType.RELAY_TRANSACTION) gateway_conn = self._add_connection(3, 9003, ALL_NETWORK_NUM, ConnectionType.EXTERNAL_GATEWAY) block_message = BroadcastMessage(Sha256Hash(helpers.generate_hash()), ALL_NETWORK_NUM, "", BroadcastMessageType.BLOCK, False, helpers.generate_bytearray(250)) self.sut.broadcast(block_message, BroadcastOptions(connection_types=[ConnectionType.RELAY_BLOCK])) tx_message = BroadcastMessage(Sha256Hash(helpers.generate_hash()), ALL_NETWORK_NUM, "", BroadcastMessageType.BLOCK, False, helpers.generate_bytearray(250)) self.sut.broadcast(tx_message, BroadcastOptions(connection_types=[ConnectionType.RELAY_TRANSACTION])) gateway_message = BroadcastMessage(Sha256Hash(helpers.generate_hash()), ALL_NETWORK_NUM, "", BroadcastMessageType.BLOCK, False, helpers.generate_bytearray(250)) self.sut.broadcast(gateway_message, BroadcastOptions(connection_types=[ConnectionType.GATEWAY])) self.assertIn(block_message, relay_all_conn.enqueued_messages) self.assertIn(block_message, relay_block_conn.enqueued_messages) self.assertNotIn(block_message, relay_transaction_conn.enqueued_messages) self.assertNotIn(block_message, gateway_conn.enqueued_messages) self.assertIn(tx_message, relay_all_conn.enqueued_messages) self.assertNotIn(tx_message, relay_block_conn.enqueued_messages) self.assertIn(tx_message, relay_transaction_conn.enqueued_messages) self.assertNotIn(tx_message, gateway_conn.enqueued_messages) self.assertNotIn(gateway_message, relay_all_conn.enqueued_messages) self.assertNotIn(gateway_message, relay_block_conn.enqueued_messages) self.assertNotIn(gateway_message, relay_transaction_conn.enqueued_messages) self.assertIn(gateway_message, gateway_conn.enqueued_messages)
def test_get_length_of_each_queuing_service_stats_format(self): block_queuing_service = self.node.build_block_queuing_service( self.node_conn) self.node.block_queuing_service_manager.add_block_queuing_service( self.node_conn, block_queuing_service) block_queuing_service_2 = self.node.build_block_queuing_service( self.node_conn_2) self.node.block_queuing_service_manager.add_block_queuing_service( self.node_conn_2, block_queuing_service_2) block_hash = Sha256Hash(helpers.generate_hash()) block_hash2 = Sha256Hash(helpers.generate_hash()) block_hash3 = Sha256Hash(helpers.generate_hash()) block_queuing_service._block_queue.append( BlockQueueEntry(block_hash, time.time())) block_queuing_service._block_queue.append( BlockQueueEntry(block_hash2, time.time())) block_queuing_service._block_queue.append( BlockQueueEntry(block_hash3, time.time())) block_queuing_service_2._block_queue.append( BlockQueueEntry(block_hash, time.time())) stats = self.node.block_queuing_service_manager.get_length_of_each_queuing_service_stats_format( ) self.assertEqual(stats, "[127.0.0.1 8002: 3, 127.0.0.1 8003: 1]")
def test_waiting_recovery_last_block_is_removed(self): block_hash1 = Sha256Hash(helpers.generate_hash()) block_msg1 = helpers.create_block_message(block_hash1) block_hash2 = Sha256Hash(helpers.generate_hash()) block_msg2 = helpers.create_block_message(block_hash2, block_hash1) block_hash3 = Sha256Hash(helpers.generate_hash()) block_msg3 = helpers.create_block_message(block_hash3, block_hash2) self.node.block_queuing_service_manager.push( block_hash1, block_msg1, waiting_for_recovery=False) self.node.block_queuing_service_manager.push( block_hash2, block_msg2, waiting_for_recovery=False) self.node.block_queuing_service_manager.push(block_hash3, block_msg3, waiting_for_recovery=True) self._assert_length_of_enqueued_messages(1) self._assert_len_of_block_queuing_services(2) self._assert_block_in_enqueued_messages_index(block_msg1, 0) self._reset_enqueue_msg_mocks() self.block_queuing_service.remove(block_hash3) self.block_queuing_service_2.remove(block_hash3) self._assert_length_of_enqueued_messages(0) self._assert_len_of_block_queuing_services(1) self._mark_blocks_seen_by_blockchain_nodes([block_hash1]) self._assert_length_of_enqueued_messages(1) self._assert_len_of_block_queuing_services(0) self._assert_block_in_enqueued_messages_index(block_msg2, 0)
def test_block_removed_with_ttl_check(self): self.node.has_active_blockchain_peer = MagicMock(return_value=False) block_hash_start = Sha256Hash(helpers.generate_hash()) block_msg_start = helpers.create_block_message(block_hash_start) block_hash_end = Sha256Hash(helpers.generate_hash()) block_msg_end = helpers.create_block_message(block_hash_end) self.node.block_queuing_service_manager.push(block_hash_start, block_msg_start) for i in range(2, BLOCK_QUEUE_LENGTH_LIMIT + 1): block_hash = Sha256Hash(helpers.generate_hash()) block_msg = helpers.create_block_message(block_hash) self.node.block_queuing_service_manager.push(block_hash, block_msg) self.assertEqual(BLOCK_QUEUE_LENGTH_LIMIT, len(self.block_queuing_service)) self._assert_length_of_enqueued_messages(0) self.node.has_active_blockchain_peer = MagicMock(return_value=True) time.time = MagicMock( return_value=time.time() + MAX_BLOCK_CACHE_TIME_S * 2 ) self.assertEqual(BLOCK_QUEUE_LENGTH_LIMIT, len(self.block_queuing_service._block_queue)) self.node.block_queuing_service_manager.push(block_hash_end, block_msg_end) self._mark_blocks_seen_by_blockchain_nodes([block_hash_end]) self.assertEqual(0, len(self.block_queuing_service._block_queue))
def test_block_added_waiting_for_previous_block_confirmation(self): block_hash_1 = Sha256Hash(helpers.generate_hash()) block_msg_1 = helpers.create_block_message(block_hash_1) block_hash_2 = Sha256Hash(helpers.generate_hash()) block_msg_2 = helpers.create_block_message(block_hash_2, block_hash_1) # first block gets sent immediately self.node.block_queuing_service_manager.push(block_hash_1, block_msg_1) self._assert_length_of_enqueued_messages(1) self._assert_block_in_enqueued_messages_index(block_msg_1, 0) self._assert_len_of_block_queuing_services(0) self._assert_block_in_queuing_services(block_hash_1) # no confirmation, wait on block 1 self.node.block_queuing_service_manager.push(block_hash_2, block_msg_2) self._assert_length_of_enqueued_messages(1) self._assert_block_in_enqueued_messages_index(block_msg_1, 0) self._assert_len_of_block_queuing_services(1) self._assert_block_in_queuing_services(block_hash_1) self._assert_block_in_queuing_services(block_hash_2) self._mark_blocks_seen_by_blockchain_nodes( [block_hash_1] ) self._assert_length_of_enqueued_messages(2) self._assert_block_in_enqueued_messages_index(block_msg_2, 1) self._assert_len_of_block_queuing_services(0)
def create_block_message( block_hash: Optional[Sha256Hash] = None, previous_block_hash: Optional[Sha256Hash] = None, ) -> TestBlockMessage: if block_hash is None: block_hash = Sha256Hash(helpers.generate_hash()) if previous_block_hash is None: previous_block_hash = Sha256Hash(helpers.generate_hash()) return TestBlockMessage(previous_block_hash, block_hash)
def test_last_block_is_recovered(self): block_hash1 = Sha256Hash(helpers.generate_hash()) block_msg1 = helpers.create_block_message() block_hash2 = Sha256Hash(helpers.generate_hash()) block_msg2 = helpers.create_block_message(block_hash2, block_hash1) block_hash3 = Sha256Hash(helpers.generate_hash()) block_msg3 = helpers.create_block_message(block_hash3, block_hash2) self.node.block_queuing_service_manager.push( block_hash1, block_msg1, waiting_for_recovery=False ) self._mark_block_seen_by_blockchain_nodes( block_hash1, None ) self.node.block_queuing_service_manager.push( block_hash2, block_msg2, waiting_for_recovery=False ) self._mark_block_seen_by_blockchain_nodes( block_hash2, None ) self.node.block_queuing_service_manager.push( block_hash3, block_msg3, waiting_for_recovery=True ) self._assert_length_of_enqueued_messages(2) self._assert_len_of_block_queuing_services(1) self._assert_block_in_enqueued_messages_index(block_msg1, 0) self._assert_block_in_enqueued_messages_index(block_msg2, 1) self._reset_enqueue_msg_mocks() self._reset_enqueue_msg_mocks() # don't send, since not recovered enough though timeout time.time = MagicMock( return_value=time.time() + MAX_INTERVAL_BETWEEN_BLOCKS_S ) self.node.alarm_queue.fire_alarms() self._assert_length_of_enqueued_messages(0) self._assert_len_of_block_queuing_services(1) self.node.block_queuing_service_manager.update_recovered_block( block_hash3, block_msg3 ) self._assert_length_of_enqueued_messages(1) self._assert_len_of_block_queuing_services(0) self._assert_block_in_enqueued_messages_index(block_msg3, 0)
def test_msg_get_block_headers_unknown(self): block_hash = helpers.generate_hash() self.sut.msg_proxy_request = MagicMock() message = GetBlockHeadersEthProtocolMessage(None, block_hash, 1, 0, 0) self.sut.msg_get_block_headers(message) self.sut.msg_proxy_request.assert_called_once()
def test_remove_block(self): block_queuing_service = self.node.build_block_queuing_service( self.node_conn) self.node.block_queuing_service_manager.add_block_queuing_service( self.node_conn, block_queuing_service) block_queuing_service.remove = MagicMock() block_queuing_service_2 = self.node.build_block_queuing_service( self.node_conn_2) self.node.block_queuing_service_manager.add_block_queuing_service( self.node_conn_2, block_queuing_service_2) block_queuing_service_2.remove = MagicMock() block_hash = Sha256Hash(helpers.generate_hash()) block_msg = helpers.create_block_message(block_hash) self.node.block_queuing_service_manager.store_block_data( block_hash, block_msg) block_queuing_service._blocks.add(block_hash) block_queuing_service_2._blocks.add(block_hash) self.assertIn(block_hash, self.node.block_storage) self.assertEqual(block_msg, self.node.block_storage[block_hash]) self.node.block_queuing_service_manager.remove(block_hash) self.assertNotIn(block_hash, self.node.block_storage) block_queuing_service.remove.assert_called_with(block_hash) block_queuing_service_2.remove.assert_called_with(block_hash)
def test_update_recovered_block(self): block_queuing_service = self.node.build_block_queuing_service( self.node_conn) self.node.block_queuing_service_manager.add_block_queuing_service( self.node_conn, block_queuing_service) block_queuing_service.update_recovered_block = MagicMock() block_queuing_service_2 = self.node.build_block_queuing_service( self.node_conn_2) self.node.block_queuing_service_manager.add_block_queuing_service( self.node_conn_2, block_queuing_service_2) block_queuing_service_2.update_recovered_block = MagicMock() block_queuing_service_3 = self.node.build_block_queuing_service( self.node_conn_3) self.node.block_queuing_service_manager.add_block_queuing_service( self.node_conn_3, block_queuing_service_3) block_queuing_service_3.update_recovered_block = MagicMock() self.assertEqual( len(self.node.block_queuing_service_manager. blockchain_peer_to_block_queuing_service), 3) block_hash = Sha256Hash(helpers.generate_hash()) block_msg = helpers.create_block_message(block_hash) self.node.block_queuing_service_manager.update_recovered_block( block_hash, block_msg) block_queuing_service.update_recovered_block.assert_called_with( block_hash, block_msg) block_queuing_service_2.update_recovered_block.assert_called_with( block_hash, block_msg) block_queuing_service_3.update_recovered_block.assert_called_with( block_hash, block_msg) self.assertIn(block_hash, self.node.block_storage) self.assertEqual(block_msg, self.node.block_storage[block_hash])
def test_waiting_recovery__timeout(self): block_hash1 = Sha256Hash(helpers.generate_hash()) block_hash2 = Sha256Hash(helpers.generate_hash()) block_msg2 = helpers.create_block_message(block_hash2) block_hash3 = Sha256Hash(helpers.generate_hash()) block_msg3 = helpers.create_block_message(block_hash3) self.node.block_queuing_service_manager.push( block_hash1, None, waiting_for_recovery=True ) self.node.block_queuing_service_manager.push( block_hash2, block_msg2, waiting_for_recovery=False ) self.node.block_queuing_service_manager.push( block_hash3, block_msg3, waiting_for_recovery=False ) self._assert_length_of_enqueued_messages(0) self._assert_len_of_block_queuing_services(3) self._assert_block_in_queuing_services(block_hash1) self._assert_block_in_queuing_services(block_hash2) self._assert_block_in_queuing_services(block_hash3) # fire alarm when block recovery not expired time.time = MagicMock( return_value=time.time() + BLOCK_RECOVERY_MAX_QUEUE_TIME / 2 + 1 ) self.node.alarm_queue.fire_alarms() self._assert_length_of_enqueued_messages(0) self._assert_len_of_block_queuing_services(3) self._assert_block_in_queuing_services(block_hash1) self._assert_block_in_queuing_services(block_hash2) self._assert_block_in_queuing_services(block_hash3) # fire alarm after recovery expires and is not successful time.time = MagicMock( return_value=time.time() + BLOCK_RECOVERY_MAX_QUEUE_TIME ) self.node.alarm_queue.fire_alarms() self._assert_length_of_enqueued_messages(1) self._assert_len_of_block_queuing_services(1) self._assert_block_in_enqueued_messages_index(block_msg2, 0) self.assertNotIn(block_hash1, self.block_queuing_service) self._assert_block_in_queuing_services(block_hash2) self._assert_block_in_queuing_services(block_hash3)
def test_top_block_is_recovered(self): block_hash1 = Sha256Hash(helpers.generate_hash()) block_msg1 = create_block_message(block_hash1) block_hash2 = Sha256Hash(helpers.generate_hash()) block_msg2 = create_block_message(block_hash2, block_hash1) block_hash3 = Sha256Hash(helpers.generate_hash()) block_msg3 = create_block_message(block_hash3, block_hash2) self.block_queuing_service.push(block_hash1, None, waiting_for_recovery=True) self.block_queuing_service.push(block_hash2, block_msg2, waiting_for_recovery=False) self.block_queuing_service.push(block_hash3, block_msg3, waiting_for_recovery=False) self.assertEqual(0, len(self.node.broadcast_to_nodes_messages)) self.assertEqual(3, len(self.block_queuing_service)) self.block_queuing_service.update_recovered_block( block_hash1, block_msg1) self.assertEqual(1, len(self.node.broadcast_to_nodes_messages)) self.assertEqual(2, len(self.block_queuing_service)) self.assertEqual(block_msg1, self.node.broadcast_to_nodes_messages[0]) del self.node.broadcast_to_nodes_messages[0] self.assertEqual(0, len(self.node.broadcast_to_nodes_messages)) self.assertEqual(2, len(self.block_queuing_service)) self.block_queuing_service.mark_blocks_seen_by_blockchain_node( [block_hash1]) self.assertEqual(1, len(self.node.broadcast_to_nodes_messages)) self.assertEqual(1, len(self.block_queuing_service)) self.assertEqual(block_msg2, self.node.broadcast_to_nodes_messages[0]) del self.node.broadcast_to_nodes_messages[0] self.block_queuing_service.mark_blocks_seen_by_blockchain_node( [block_hash2]) self.assertEqual(1, len(self.node.broadcast_to_nodes_messages)) self.assertEqual(0, len(self.block_queuing_service)) self.assertEqual(block_msg3, self.node.broadcast_to_nodes_messages[0])
def test_try_process_get_block_bodies_request_not_found(self): success = self.block_processing_service.try_process_get_block_bodies_request( GetBlockBodiesEthProtocolMessage( None, [self.block_hashes[0].binary, bytes(helpers.generate_hash())])) self.assertFalse(success) self.node.broadcast.assert_not_called()
def test_sending_headers_to_node_recovery(self): block_hash = Sha256Hash(helpers.generate_hash()) self.node.block_queuing_service_manager.push( block_hash, None, waiting_for_recovery=True ) success = self.block_queuing_service.try_send_header_to_node(block_hash) self.assertFalse(success) self._assert_length_of_enqueued_messages(0)
def test_waiting_recovery__timeout(self): block_hash1 = Sha256Hash(helpers.generate_hash()) block_hash2 = Sha256Hash(helpers.generate_hash()) block_msg2 = create_block_message(block_hash2) block_hash3 = Sha256Hash(helpers.generate_hash()) block_msg3 = create_block_message(block_hash3) self.block_queuing_service.push(block_hash1, None, waiting_for_recovery=True) self.block_queuing_service.push(block_hash2, block_msg2, waiting_for_recovery=False) self.block_queuing_service.push(block_hash3, block_msg3, waiting_for_recovery=False) self.assertEqual(0, len(self.node.broadcast_to_nodes_messages)) self.assertEqual(3, len(self.block_queuing_service)) self.assertIn(block_hash1, self.block_queuing_service) self.assertIn(block_hash2, self.block_queuing_service) self.assertIn(block_hash3, self.block_queuing_service) # fire alarm when block recovery not expired time.time = MagicMock(return_value=time.time() + BLOCK_RECOVERY_MAX_QUEUE_TIME / 2 + 1) self.node.alarm_queue.fire_alarms() self.assertEqual(0, len(self.node.broadcast_to_nodes_messages)) self.assertEqual(3, len(self.block_queuing_service)) self.assertIn(block_hash1, self.block_queuing_service) self.assertIn(block_hash2, self.block_queuing_service) self.assertIn(block_hash3, self.block_queuing_service) # fire alarm after recovery expires and is not successful time.time = MagicMock(return_value=time.time() + BLOCK_RECOVERY_MAX_QUEUE_TIME) self.node.alarm_queue.fire_alarms() self.assertEqual(1, len(self.node.broadcast_to_nodes_messages)) self.assertEqual(1, len(self.block_queuing_service)) self.assertEqual(block_msg2, self.node.broadcast_to_nodes_messages[0]) self.assertNotIn(block_hash1, self.block_queuing_service) self.assertIn(block_hash2, self.block_queuing_service) self.assertIn(block_hash3, self.block_queuing_service)
def test_waiting_recovery_block_to_empty_queue(self): block_hash = Sha256Hash(helpers.generate_hash()) self.block_queuing_service.push(block_hash, None, waiting_for_recovery=True) self.assertEqual(0, len(self.node.broadcast_to_nodes_messages)) self.assertEqual(1, len(self.block_queuing_service)) self.assertIn(block_hash, self.block_queuing_service)
def test_waiting_recovery_block_to_empty_queue(self): block_hash = Sha256Hash(helpers.generate_hash()) self.node.block_queuing_service_manager.push( block_hash, None, waiting_for_recovery=True ) self._assert_length_of_enqueued_messages(0) self._assert_len_of_block_queuing_services(1) self._assert_block_in_queuing_services(block_hash)
def test_sending_headers_to_node_recovery(self): block_hash = Sha256Hash(helpers.generate_hash()) self.block_queuing_service.push(block_hash, None, waiting_for_recovery=True) success = self.block_queuing_service.try_send_header_to_node( block_hash) self.assertFalse(success) self.assertEqual(0, len(self.node.broadcast_to_nodes_messages))
def test_waiting_recovery_top_block_timeout(self): block_hash1 = Sha256Hash(helpers.generate_hash()) block_hash2 = Sha256Hash(helpers.generate_hash()) block_msg2 = helpers.create_block_message(block_hash2, block_hash1) block_hash3 = Sha256Hash(helpers.generate_hash()) block_msg3 = helpers.create_block_message(block_hash3, block_hash2) self.node.block_queuing_service_manager.push( block_hash1, None, waiting_for_recovery=True ) self.node.block_queuing_service_manager.push( block_hash2, block_msg2, waiting_for_recovery=False ) self.node.block_queuing_service_manager.push( block_hash3, block_msg3, waiting_for_recovery=False ) self._assert_length_of_enqueued_messages(0) self._assert_len_of_block_queuing_services(3) self._assert_block_in_queuing_services(block_hash1) self._assert_block_in_queuing_services(block_hash2) self._assert_block_in_queuing_services(block_hash3) # trigger automatic removal of top block recovery time.time = MagicMock( return_value=time.time() + gateway_constants.BLOCK_RECOVERY_MAX_QUEUE_TIME ) self.node.alarm_queue.fire_alarms() self._assert_length_of_enqueued_messages(1) self._assert_len_of_block_queuing_services(1) self._assert_block_in_enqueued_messages_index(block_msg2, 0) self._reset_enqueue_msg_mocks() self._mark_blocks_seen_by_blockchain_nodes( [block_hash2] ) self._assert_length_of_enqueued_messages(1) self._assert_len_of_block_queuing_services(0) self._assert_block_in_enqueued_messages_index(block_msg3, 0)
def test_last_block_is_recovered(self): block_hash1 = Sha256Hash(helpers.generate_hash()) block_msg1 = create_block_message() block_hash2 = Sha256Hash(helpers.generate_hash()) block_msg2 = create_block_message(block_hash2, block_hash1) block_hash3 = Sha256Hash(helpers.generate_hash()) block_msg3 = create_block_message(block_hash3, block_hash2) self.block_queuing_service.push(block_hash1, block_msg1, waiting_for_recovery=False) self.block_queuing_service.mark_block_seen_by_blockchain_node( block_hash1, None) self.block_queuing_service.push(block_hash2, block_msg2, waiting_for_recovery=False) self.block_queuing_service.mark_block_seen_by_blockchain_node( block_hash2, None) self.block_queuing_service.push(block_hash3, block_msg3, waiting_for_recovery=True) self.assertEqual(2, len(self.node.broadcast_to_nodes_messages)) self.assertEqual(1, len(self.block_queuing_service)) self.assertEqual(block_msg1, self.node.broadcast_to_nodes_messages[0]) self.assertEqual(block_msg2, self.node.broadcast_to_nodes_messages[1]) self.node.broadcast_to_nodes_messages = [] # don't send, since not recovered enough though timeout time.time = MagicMock(return_value=time.time() + MAX_INTERVAL_BETWEEN_BLOCKS_S) self.node.alarm_queue.fire_alarms() self.assertEqual(0, len(self.node.broadcast_to_nodes_messages)) self.assertEqual(1, len(self.block_queuing_service)) self.block_queuing_service.update_recovered_block( block_hash3, block_msg3) self.assertEqual(1, len(self.node.broadcast_to_nodes_messages)) self.assertEqual(0, len(self.block_queuing_service)) self.assertEqual(block_msg3, self.node.broadcast_to_nodes_messages[0])
def test_waiting_recovery_top_block_timeout(self): block_hash1 = Sha256Hash(helpers.generate_hash()) block_hash2 = Sha256Hash(helpers.generate_hash()) block_msg2 = create_block_message(block_hash2, block_hash1) block_hash3 = Sha256Hash(helpers.generate_hash()) block_msg3 = create_block_message(block_hash3, block_hash2) self.block_queuing_service.push(block_hash1, None, waiting_for_recovery=True) self.block_queuing_service.push(block_hash2, block_msg2, waiting_for_recovery=False) self.block_queuing_service.push(block_hash3, block_msg3, waiting_for_recovery=False) self.assertEqual(0, len(self.node.broadcast_to_nodes_messages)) self.assertEqual(3, len(self.block_queuing_service)) self.assertIn(block_hash1, self.block_queuing_service) self.assertIn(block_hash2, self.block_queuing_service) self.assertIn(block_hash3, self.block_queuing_service) # trigger automatic removal of top block recovery time.time = MagicMock(return_value=time.time() + gateway_constants.BLOCK_RECOVERY_MAX_QUEUE_TIME) self.node.alarm_queue.fire_alarms() self.assertEqual(1, len(self.node.broadcast_to_nodes_messages)) self.assertEqual(1, len(self.block_queuing_service)) self.assertEqual(block_msg2, self.node.broadcast_to_nodes_messages[0]) del self.node.broadcast_to_nodes_messages[0] self.block_queuing_service.mark_blocks_seen_by_blockchain_node( [block_hash2]) self.assertEqual(1, len(self.node.broadcast_to_nodes_messages)) self.assertEqual(0, len(self.block_queuing_service)) self.assertEqual(block_msg3, self.node.broadcast_to_nodes_messages[0])
async def test_subscription_with_no_content_filled(self): tx_hash = helpers.generate_hash() await self.eth_ws_server_message_queue.put(f"0x{convert.bytes_to_hex(tx_hash)}") await asyncio.sleep(0.01) self.assertEqual(1, self.subscriber.messages.qsize()) tx_message = await self.subscriber.receive() self.assertEqual(f"0x{convert.bytes_to_hex(tx_hash)}", tx_message.tx_hash) expected_contents = self.sample_transactions[2].to_json() self.assertEqual(expected_contents, tx_message.tx_contents)
def test_broadcast_to_network_numbers(self): all_matching_network_num = self._add_connection(0, 9000, ALL_NETWORK_NUM) matching_network_num = self._add_connection(1, 9001, 1) not_matching_network_num = self._add_connection(2, 9002, 2) message = BroadcastMessage(Sha256Hash(helpers.generate_hash()), 1, "", BroadcastMessageType.BLOCK, False, helpers.generate_bytearray(250)) self.sut.broadcast(message, BroadcastOptions(connection_types=[MockConnection.CONNECTION_TYPE])) self.assertIn(message, all_matching_network_num.enqueued_messages) self.assertIn(message, matching_network_num.enqueued_messages) self.assertNotIn(message, not_matching_network_num.enqueued_messages)
def test_sending_headers_to_node(self): block_hash = Sha256Hash(helpers.generate_hash()) block_message = create_block_message(block_hash) self.block_queuing_service.push(block_hash, block_message) success = self.block_queuing_service.try_send_header_to_node( block_hash) self.assertTrue(success) self.assertEqual(2, len(self.node.broadcast_to_nodes_messages)) block_header_message = self.node.broadcast_to_nodes_messages[1] self.assertIsInstance(block_header_message, TestBlockHeaderMessage) self.assertEqual(block_hash, block_header_message.block_hash)
def test_store_block_data(self): block_queuing_service = self.node.build_block_queuing_service( self.node_conn) self.node.block_queuing_service_manager.add_block_queuing_service( self.node_conn, block_queuing_service) block_hash = Sha256Hash(helpers.generate_hash()) block_msg = helpers.create_block_message(block_hash) self.node.block_queuing_service_manager.store_block_data( block_hash, block_msg) self.assertIn(block_hash, self.node.block_storage) self.assertEqual(block_msg, self.node.block_storage[block_hash])
def test_block_added_send_immediately_with_confirmation(self): block_hash_1 = Sha256Hash(helpers.generate_hash()) block_msg_1 = helpers.create_block_message(block_hash_1) block_hash_2 = Sha256Hash(helpers.generate_hash()) block_msg_2 = helpers.create_block_message(block_hash_2, block_hash_1) # first block gets sent immediately self.node.block_queuing_service_manager.push(block_hash_1, block_msg_1) self._assert_length_of_enqueued_messages(1) self._assert_block_in_enqueued_messages_index(block_msg_1, 0) self._assert_len_of_block_queuing_services(0) self._assert_block_in_queuing_services(block_hash_1) # confirmed, send immediately self._mark_block_seen_by_blockchain_nodes(block_hash_1, None) self.node.block_queuing_service_manager.push(block_hash_2, block_msg_2) self._assert_length_of_enqueued_messages(2) self._assert_block_in_enqueued_messages_index(block_msg_2, 1) self._assert_len_of_block_queuing_services(0) self._assert_block_in_queuing_services(block_hash_1) self._assert_block_in_queuing_services(block_hash_2)
def test_push_block_queuing_service(self): block_queuing_service = self.node.build_block_queuing_service( self.node_conn) self.node.block_queuing_service_manager.add_block_queuing_service( self.node_conn, block_queuing_service) block_queuing_service.push = MagicMock() block_queuing_service_2 = self.node.build_block_queuing_service( self.node_conn_2) self.node.block_queuing_service_manager.add_block_queuing_service( self.node_conn_2, block_queuing_service_2) block_queuing_service_2.push = MagicMock() block_queuing_service_3 = self.node.build_block_queuing_service( self.node_conn_3) self.node.block_queuing_service_manager.add_block_queuing_service( self.node_conn_3, block_queuing_service_3) block_queuing_service_3.push = MagicMock() block_hash = Sha256Hash(helpers.generate_hash()) block_msg = helpers.create_block_message(block_hash) self.node.block_queuing_service_manager.push(block_hash, block_msg) block_queuing_service.push.assert_called_with(block_hash, block_msg, False) block_queuing_service_2.push.assert_called_with( block_hash, block_msg, False) block_queuing_service_3.push.assert_called_with( block_hash, block_msg, False) block_hash2 = Sha256Hash(helpers.generate_hash()) block_msg2 = helpers.create_block_message(block_hash) self.node.block_queuing_service_manager.push(block_hash2, block_msg2, waiting_for_recovery=True) block_queuing_service.push.assert_called_with(block_hash2, block_msg2, True) block_queuing_service_2.push.assert_called_with( block_hash2, block_msg2, True) block_queuing_service_3.push.assert_called_with( block_hash2, block_msg2, True)