Esempio n. 1
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))
Esempio n. 2
0
    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)
Esempio n. 3
0
    def test_block_queue_continues_after_timeout(self):
        block_hash_1 = helpers.generate_object_hash()
        block_msg_1 = helpers.create_block_message(block_hash_1)

        block_hash_2 = helpers.generate_object_hash()
        block_msg_2 = helpers.create_block_message(block_hash_2, block_hash_1)

        block_hash_3 = helpers.generate_object_hash()
        block_msg_3 = helpers.create_block_message(block_hash_3, block_hash_2)

        self.node.has_active_blockchain_peer = MagicMock(return_value=False)

        self.node.block_queuing_service_manager.push(block_hash_1, block_msg_1)
        time.time = MagicMock(return_value=time.time() + 150)

        self.node.block_queuing_service_manager.push(block_hash_2, block_msg_2)
        self.node.block_queuing_service_manager.push(block_hash_3, block_msg_3)
        time.time = MagicMock(return_value=time.time() + TTL - 150 + 1)

        # too much time has elapsed for the first message
        self.node.has_active_blockchain_peer = MagicMock(return_value=True)
        self.node.alarm_queue.fire_alarms()

        self._assert_length_of_enqueued_messages(1)
        self._assert_block_in_enqueued_messages_index(block_msg_2, 0)
    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)
Esempio n. 5
0
    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)
Esempio n. 6
0
    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_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_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)
Esempio n. 9
0
    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)
Esempio n. 10
0
    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_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)
Esempio n. 14
0
    def test_sending_block_timed_out(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)

        self.node.block_queuing_service_manager.push(block_hash_2, block_msg_2)

        time.time = MagicMock(return_value=time.time() + 350)

        # too much time has elapsed, message is dropped
        self.node.alarm_queue.fire_alarms()
        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)
Esempio n. 15
0
    def test_sending_headers_to_node(self):
        block_hash = Sha256Hash(helpers.generate_hash())
        block_message = helpers.create_block_message(block_hash)
        self.node.block_queuing_service_manager.push(block_hash, block_message)
        success = self.block_queuing_service.try_send_header_to_node(block_hash)
        self.assertTrue(success)
        success = self.block_queuing_service_2.try_send_header_to_node(block_hash)
        self.assertTrue(success)

        self._assert_length_of_enqueued_messages(2)

        block_header_message = self._get_enqueued_messages(self.node_conn)[1]
        self.assertIsInstance(block_header_message, TestBlockHeaderMessage)
        self.assertEqual(block_hash, block_header_message.block_hash)
        block_header_message = self._get_enqueued_messages(self.node_conn_2)[1]
        self.assertIsInstance(block_header_message, TestBlockHeaderMessage)
        self.assertEqual(block_hash, block_header_message.block_hash)
    def test_block_added_to_empty_queue(self):
        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, waiting_for_recovery=False)

        self._assert_length_of_enqueued_messages(1)
        self._assert_block_in_enqueued_messages_index(block_msg, 0)

        self._assert_len_of_block_queuing_services(0)
        self._assert_len_of_blocks_sent(1)
        self.assertEqual(block_hash, self.block_queuing_service.blocks_sent[0])

        # block still in service after confirmation
        self._assert_block_in_queuing_services(block_hash)
        self._mark_block_seen_by_blockchain_nodes(block_hash, None)
        self._assert_block_in_queuing_services(block_hash)
Esempio n. 17
0
    def test_block_added_when_node_is_not_ready(self):
        self.node.has_active_blockchain_peer = MagicMock(return_value=False)

        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, waiting_for_recovery=False
        )

        self._assert_length_of_enqueued_messages(0)
        self._assert_len_of_block_queuing_services(1)
        self._assert_block_in_queuing_services(block_hash)

        time.time = MagicMock(
            return_value=time.time()
            + NODE_READINESS_FOR_BLOCKS_CHECK_INTERVAL_S
        )
        self.node.alarm_queue.fire_alarms()

        # verify that item is still in the queue if node connection
        # is still not available
        self._assert_length_of_enqueued_messages(0)
        self._assert_len_of_block_queuing_services(1)
        self._assert_block_in_queuing_services(block_hash)

        self.node.has_active_blockchain_peer = MagicMock(return_value=True)

        time.time = MagicMock(
            return_value=time.time()
            + NODE_READINESS_FOR_BLOCKS_CHECK_INTERVAL_S * 2
        )
        self.node.alarm_queue.fire_alarms()

        # verify that is sent to node once connection to node is active
        self._assert_length_of_enqueued_messages(1)
        self._assert_block_in_enqueued_messages_index(block_msg, 0)
        self._assert_len_of_block_queuing_services(0)

        # verify item still cached, since confirmation not received
        self._assert_block_in_queuing_services(block_hash)