Ejemplo n.º 1
0
    def test_get_txs_block_recovery_encrypted(self):
        block: BlockOntMessage = self.ont_block()
        transactions: List[TxOntMessage] = self.ont_transactions(block)

        # assign short ids that the local connection won't know about until it gets the txs message
        remote_transaction_service = ExtensionTransactionService(
            MockNode(gateway_helpers.get_gateway_opts(8999)), 0)
        short_id_mapping = {}
        for i, transaction in enumerate(transactions):
            tx_hash = transaction.tx_hash()
            transaction_key = remote_transaction_service.get_transaction_key(
                tx_hash)

            remote_transaction_service.assign_short_id_by_key(
                transaction_key, i + 1)
            remote_transaction_service.set_transaction_contents_by_key(
                transaction_key, transaction.rawbytes())
            short_id_mapping[tx_hash] = TransactionInfo(
                tx_hash, transaction.rawbytes(), i + 1)

        bx_block = bytes(
            self.gateway_node.message_converter.block_to_bx_block(
                block, remote_transaction_service, True,
                self.gateway_node.network.min_tx_age_seconds)[0])

        self.gateway_node.block_recovery_service.add_block = \
            MagicMock(wraps=self.gateway_node.block_recovery_service.add_block)
        self.gateway_node.broadcast = MagicMock()

        key, ciphertext = symmetric_encrypt(bx_block)
        block_hash = crypto.double_sha256(ciphertext)
        key_message = KeyMessage(Sha256Hash(block_hash), DEFAULT_NETWORK_NUM,
                                 "", key)
        broadcast_message = BroadcastMessage(Sha256Hash(block_hash),
                                             DEFAULT_NETWORK_NUM, "",
                                             BroadcastMessageType.BLOCK, True,
                                             ciphertext)

        self.sut.msg_broadcast(broadcast_message)

        self.gateway_node.broadcast.reset_mock()
        self.sut.msg_key(key_message)

        self.gateway_node.block_recovery_service.add_block.assert_called_once()
        self.assertEqual(2, self.gateway_node.broadcast.call_count)

        recovery_broadcast = self.gateway_node.broadcast.call_args_list[0]
        ((gettxs_message, ), recovery_kwargs) = recovery_broadcast
        self.assertIsInstance(gettxs_message, GetTxsMessage)
        self.assertIn(ConnectionType.RELAY_TRANSACTION,
                      recovery_kwargs["connection_types"])

        key_broadcast = self.gateway_node.broadcast.call_args_list[1]
        ((key_message, _conn), recovery_kwargs) = key_broadcast
        self.assertIsInstance(key_message, KeyMessage)
        self.assertIn(ConnectionType.GATEWAY,
                      recovery_kwargs["connection_types"])

        txs = [tx for tx in short_id_mapping.values()]
        txs_message = TxsMessage(txs=txs)
        self.sut.msg_txs(txs_message)

        self._assert_block_sent(block)
Ejemplo n.º 2
0
    def test_msg_broadcast_duplicate_block_with_different_short_id(self):
        # test scenario when first received block is compressed with unknown short ids,
        # but second received block is compressed with known short ids
        ont_block = self.ont_block()
        block_hash = ont_block.block_hash()
        transactions = self.bx_transactions()

        unknown_sid_transaction_service = ExtensionTransactionService(
            MockNode(gateway_helpers.get_gateway_opts(8999)), 0)
        for i, transaction in enumerate(transactions):
            transaction_key = unknown_sid_transaction_service.get_transaction_key(
                transaction.tx_hash())
            unknown_sid_transaction_service.assign_short_id_by_key(
                transaction_key, i)
            unknown_sid_transaction_service.set_transaction_contents_by_key(
                transaction_key, transaction.tx_val())

        unknown_short_id_block = bytes(
            self.gateway_node.message_converter.block_to_bx_block(
                ont_block, unknown_sid_transaction_service, True,
                self.gateway_node.network.min_tx_age_seconds)[0])
        unknown_key, unknown_cipher = symmetric_encrypt(unknown_short_id_block)
        unknown_block_hash = crypto.double_sha256(unknown_cipher)
        unknown_message = BroadcastMessage(Sha256Hash(unknown_block_hash),
                                           self.TEST_NETWORK_NUM, "",
                                           BroadcastMessageType.BLOCK, False,
                                           bytearray(unknown_short_id_block))
        unknown_key_message = KeyMessage(Sha256Hash(unknown_block_hash),
                                         self.TEST_NETWORK_NUM, "",
                                         unknown_key)

        local_transaction_service = self.gateway_node.get_tx_service()
        for i, transaction in enumerate(transactions):
            transaction_key = local_transaction_service.get_transaction_key(
                transaction.tx_hash())
            local_transaction_service.assign_short_id_by_key(
                transaction_key, i + 20)
            local_transaction_service.set_transaction_contents_by_key(
                transaction_key, transaction.tx_val())

        known_short_id_block = bytes(
            self.gateway_node.message_converter.block_to_bx_block(
                ont_block, local_transaction_service, True,
                self.gateway_node.network.min_tx_age_seconds)[0])
        known_key, known_cipher = symmetric_encrypt(known_short_id_block)
        known_block_hash = crypto.double_sha256(known_cipher)
        known_message = BroadcastMessage(Sha256Hash(known_block_hash),
                                         self.TEST_NETWORK_NUM, "",
                                         BroadcastMessageType.BLOCK, False,
                                         bytearray(known_short_id_block))
        known_key_message = KeyMessage(Sha256Hash(known_block_hash),
                                       self.TEST_NETWORK_NUM, "", known_key)

        self.sut.msg_broadcast(unknown_message)
        self.sut.msg_key(unknown_key_message)

        block_queuing_service = self.gateway_node.block_queuing_service_manager.get_block_queuing_service(
            self.node_conn)
        self.assertEqual(1, len(block_queuing_service))
        self.assertEqual(
            True,
            block_queuing_service._blocks_waiting_for_recovery[block_hash])
        self.assertEqual(
            1,
            len(self.gateway_node.block_recovery_service.
                _block_hash_to_bx_block_hashes))
        self.assertNotIn(block_hash, self.gateway_node.blocks_seen.contents)

        self.sut.msg_broadcast(known_message)
        self.sut.msg_key(known_key_message)
        self.gateway_node_sut.msg_get_data(
            GetDataOntMessage(self.magic, InventoryOntType.MSG_BLOCK.value,
                              block_hash))

        self.gateway_node.broadcast.assert_called()
        self.assertEqual(0, len(block_queuing_service))
        self.assertEqual(
            0,
            len(self.gateway_node.block_recovery_service.
                _block_hash_to_bx_block_hashes))
        self.assertIn(block_hash, self.gateway_node.blocks_seen.contents)