def msg_inv(self, msg: InvOntMessage) -> None:
        if not self.node.should_process_block_hash():
            return

        contains_block = False
        inventory_requests = []
        block_hashes = []
        inventory_type, item_hashes = msg.inv_type()

        if inventory_type == InventoryOntType.MSG_BLOCK.value:
            for item_hash in item_hashes:
                block_hashes.append(item_hash)
                if item_hash not in self.node.blocks_seen.contents:
                    contains_block = True
                    inventory_requests.append(item_hash)
        else:
            for item_hash in item_hashes:
                inventory_requests.append(item_hash)

        # TODO: mark_blocks_and_request_cleanup

        for req in inventory_requests:
            get_data = GetDataOntMessage(
                magic=msg.magic(),
                inv_type=inventory_type,
                block=req
            )
            self.connection.enqueue_msg(get_data, prepend=contains_block)

        block_queuing_service = self.node.block_queuing_service_manager.get_block_queuing_service(self.connection)
        if block_queuing_service is not None:
            block_queuing_service.mark_blocks_seen_by_blockchain_node(block_hashes)
 def _request_block(self, block_hash: Sha256Hash) -> None:
     block_request_message = GetDataOntMessage(
         magic=self.node.opts.blockchain_net_magic,
         inv_type=InventoryOntType.MSG_BLOCK.value,
         block=block_hash
     )
     self.node.send_msg_to_node(block_request_message)
     logger.trace("Received block cleanup request: {}", block_hash)
    def test_inv_and_get_data(self):
        seen_block_hash = OntObjectHash(buf=helpers.generate_bytearray(ONT_HASH_LEN), length=ONT_HASH_LEN)
        not_seen_block_hash = OntObjectHash(buf=helpers.generate_bytearray(ONT_HASH_LEN), length=ONT_HASH_LEN)
        self.node.blocks_seen.add(seen_block_hash)

        inv_msg_seen_block = InvOntMessage(123, InventoryOntType.MSG_BLOCK, [seen_block_hash, seen_block_hash])
        self.sut.msg_inv(inv_msg_seen_block)
        get_data_msg_msg_seen_bytes = self.sut.connection.get_bytes_to_send()
        self.assertEqual(0, len(get_data_msg_msg_seen_bytes))

        inv_msg = InvOntMessage(123, InventoryOntType.MSG_BLOCK, [seen_block_hash, not_seen_block_hash])
        self.sut.msg_inv(inv_msg)
        get_data_msg_bytes = self.sut.connection.get_bytes_to_send()
        get_data_msg = GetDataOntMessage(buf=get_data_msg_bytes)
        data_msg_inv_type, data_msg_block = get_data_msg.inv_type()
        self.assertEqual(InventoryOntType.MSG_BLOCK.value, data_msg_inv_type)
        self.assertEqual(not_seen_block_hash, data_msg_block)
    def msg_headers(self, msg: HeadersOntMessage):
        if not self.node.should_process_block_hash():
            return

        header = msg.headers()[-1]
        raw_hash = crypto.double_sha256(header)
        reply = GetDataOntMessage(self.magic, InventoryOntType.MSG_BLOCK.value,
                                  OntObjectHash(buf=raw_hash, length=ont_constants.ONT_HASH_LEN))
        self.connection.enqueue_msg(reply)
예제 #5
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):
            unknown_sid_transaction_service.assign_short_id(transaction.tx_hash(), i)
            unknown_sid_transaction_service.set_transaction_contents(transaction.tx_hash(), 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):
            local_transaction_service.assign_short_id(transaction.tx_hash(), i + 20)
            local_transaction_service.set_transaction_contents(transaction.tx_hash(), 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)

        self.assertEqual(1, len(self.gateway_node.block_queuing_service))
        self.assertEqual(True, self.gateway_node.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(self.gateway_node.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)
예제 #6
0
 def msg_get_data(self, msg: GetDataOntMessage) -> None:
     inventory_type, item_hash = msg.inv_type()
     if inventory_type == InventoryOntType.MSG_BLOCK.value:
         block_stats.add_block_event_by_block_hash(
             item_hash,
             BlockStatEventType.REMOTE_BLOCK_REQUESTED_BY_GATEWAY,
             network_num=self.connection.network_num,
             more_info="Protocol: {}, Network: {}".format(
                 self.node.opts.blockchain_protocol,
                 self.node.opts.blockchain_network))
     self.node.block_queuing_service.send_block_to_nodes(item_hash)
예제 #7
0
 def _request_block(self, block_hash: Sha256Hash) -> None:
     block_request_message = GetDataOntMessage(
         magic=self.node.opts.blockchain_net_magic,
         inv_type=InventoryOntType.MSG_BLOCK.value,
         # pyre-fixme[6]: Expected `[OntObjectHash]` for 3rd parameter but got `Sha256Hash`
         block=block_hash
     )
     node_conn = typing.cast("bxgateway.connections.ont.ont_node_connection.OntNodeConnection",
                             self.node.get_any_active_blockchain_connection())
     if node_conn is None:
         logger.debug("Request for block '{}' failed. No connection to node.", repr(block_hash))
         return
     node_conn.enqueue_msg(block_request_message)
     logger.trace("Received block cleanup request: {}", block_hash)
예제 #8
0
    def test_peek_message_success_all_types(self):
        self.get_message_preview_successfully(self.VERSION_ONT_MESSAGE,
                                              VersionOntMessage.MESSAGE_TYPE,
                                              83)
        self.get_message_preview_successfully(
            VerAckOntMessage(self.MAGIC, True), VerAckOntMessage.MESSAGE_TYPE,
            1)
        self.get_message_preview_successfully(PingOntMessage(self.MAGIC),
                                              PingOntMessage.MESSAGE_TYPE, 8)
        self.get_message_preview_successfully(PongOntMessage(self.MAGIC, 123),
                                              PongOntMessage.MESSAGE_TYPE, 8)
        self.get_message_preview_successfully(GetAddrOntMessage(self.MAGIC),
                                              GetAddrOntMessage.MESSAGE_TYPE,
                                              0)
        self.get_message_preview_successfully(
            AddrOntMessage(
                self.MAGIC,
                [(int(time.time()), 123, "127.0.0.1", 20300, 20200, 1234)]),
            AddrOntMessage.MESSAGE_TYPE, 52)
        self.get_message_preview_successfully(
            OntConsensusMessage(self.MAGIC, self.VERSION, bytes(20)),
            OntConsensusMessage.MESSAGE_TYPE, 24)

        self.get_message_preview_successfully(
            InvOntMessage(self.MAGIC, InventoryOntType.MSG_TX,
                          [self.HASH, self.HASH]), InvOntMessage.MESSAGE_TYPE,
            69)
        self.get_message_preview_successfully(
            GetDataOntMessage(self.MAGIC, 1, self.HASH),
            GetDataOntMessage.MESSAGE_TYPE, 33)
        self.get_message_preview_successfully(
            GetHeadersOntMessage(self.MAGIC, 1, self.HASH, self.HASH),
            GetHeadersOntMessage.MESSAGE_TYPE, 65)
        self.get_message_preview_successfully(
            GetBlocksOntMessage(self.MAGIC, 1, self.HASH, self.HASH),
            GetBlocksOntMessage.MESSAGE_TYPE, 65)
        self.get_message_preview_successfully(
            TxOntMessage(self.MAGIC, self.VERSION, bytes(20)),
            TxOntMessage.MESSAGE_TYPE, 21)
        self.get_message_preview_successfully(
            BlockOntMessage(self.MAGIC, self.VERSION, self.HASH, self.HASH,
                            self.HASH, 0, 0, 0, bytes(10), bytes(20),
                            [bytes(33)] * 5, [bytes(2)] * 3, [bytes(32)] * 5,
                            self.HASH), BlockOntMessage.MESSAGE_TYPE, 524)
        self.get_message_preview_successfully(
            HeadersOntMessage(self.MAGIC, [bytes(1)] * 2),
            HeadersOntMessage.MESSAGE_TYPE, 6)
        self.get_message_preview_successfully(
            NotFoundOntMessage(self.MAGIC, self.HASH),
            NotFoundOntMessage.MESSAGE_TYPE, 32)
예제 #9
0
 def test_parse_message_success_all_types(self):
     self.create_message_successfully(self.VERSION_ONT_MESSAGE,
                                      VersionOntMessage)
     self.create_message_successfully(VerAckOntMessage(self.MAGIC, False),
                                      VerAckOntMessage)
     self.create_message_successfully(PingOntMessage(self.MAGIC),
                                      PingOntMessage)
     self.create_message_successfully(PongOntMessage(self.MAGIC, 123),
                                      PongOntMessage)
     self.create_message_successfully(GetAddrOntMessage(self.MAGIC),
                                      GetAddrOntMessage)
     self.create_message_successfully(
         AddrOntMessage(
             self.MAGIC,
             [(int(time.time()), 123, "127.0.0.1", 20300, 20200, 1234)]),
         AddrOntMessage)
     self.create_message_successfully(
         OntConsensusMessage(self.MAGIC, self.VERSION, bytes(20)),
         OntConsensusMessage)
     self.create_message_successfully(
         InvOntMessage(self.MAGIC, InventoryOntType.MSG_TX,
                       [self.HASH, self.HASH]), InvOntMessage)
     self.create_message_successfully(
         GetDataOntMessage(self.MAGIC, 1, self.HASH), GetDataOntMessage)
     self.create_message_successfully(
         GetHeadersOntMessage(self.MAGIC, 1, self.HASH, self.HASH),
         GetHeadersOntMessage)
     self.create_message_successfully(
         GetBlocksOntMessage(self.MAGIC, 1, self.HASH, self.HASH),
         GetBlocksOntMessage)
     self.create_message_successfully(
         TxOntMessage(self.MAGIC, self.VERSION, bytes(20)), TxOntMessage)
     self.create_message_successfully(
         BlockOntMessage(self.MAGIC, self.VERSION, self.HASH, self.HASH,
                         self.HASH, 0, 0, 0, bytes(10), bytes(20),
                         [bytes(33)] * 5, [bytes(2)] * 3, [bytes(32)] * 5,
                         self.HASH), BlockOntMessage)
     self.create_message_successfully(
         HeadersOntMessage(self.MAGIC, [bytes(1)] * 2), HeadersOntMessage)
     self.create_message_successfully(
         NotFoundOntMessage(self.MAGIC, self.HASH), NotFoundOntMessage)