def process_transactions_message_from_node(
            self, msg) -> List[ProcessTransactionMessageFromNodeResult]:
        opts = cast(GatewayOpts, self.node.opts)
        msg_bytes = msg.rawbytes()

        if isinstance(self.node,
                      OntGatewayNode) and opts.process_node_txs_in_extension:
            ext_processing_results = memoryview(
                self.proxy.process_gateway_transaction_from_node(
                    BlockchainProtocol.ONTOLOGY.value,
                    tpe.InputBytes(msg_bytes)))
        elif isinstance(self.node,
                        EthGatewayNode) and opts.process_node_txs_in_extension:
            ext_processing_results = memoryview(
                self.proxy.process_gateway_transaction_from_node(
                    BlockchainProtocol.ETHEREUM.value,
                    tpe.InputBytes(msg_bytes)))
        else:
            return GatewayTransactionService.process_transactions_message_from_node(
                self, msg)

        result = []

        offset = 0

        txs_count, = struct.unpack_from("<I", ext_processing_results, offset)
        offset += constants.UL_INT_SIZE_IN_BYTES

        while offset < len(ext_processing_results):
            seen, = struct.unpack_from("<?", ext_processing_results, offset)
            offset += 1

            tx_hash = Sha256Hash(
                ext_processing_results[offset:offset + crypto.SHA256_HASH_LEN])
            offset += crypto.SHA256_HASH_LEN
            tx_offset, = struct.unpack_from("<I", ext_processing_results,
                                            offset)
            offset += constants.UL_INT_SIZE_IN_BYTES
            tx_len, = struct.unpack_from("<I", ext_processing_results, offset)
            offset += constants.UL_INT_SIZE_IN_BYTES

            tx_contents = msg_bytes[tx_offset:tx_offset + tx_len]

            result.append(
                ProcessTransactionMessageFromNodeResult(
                    seen, tx_hash, tx_contents,
                    TxMessage(message_hash=tx_hash,
                              network_num=self.network_num,
                              tx_val=tx_contents)))

            if not seen:
                transaction_cache_key = self._tx_hash_to_cache_key(tx_hash)
                self.set_transaction_contents_base(tx_hash,
                                                   transaction_cache_key,
                                                   tx_contents, False, 0,
                                                   False)

        assert txs_count == len(result)

        return result
    def _tx_hash_to_cache_key(self,
                              transaction_hash) -> tpe.Sha256:  # pyre-ignore
        if isinstance(transaction_hash, Sha256Hash):
            return tpe.Sha256(tpe.InputBytes(transaction_hash.binary))

        if isinstance(transaction_hash, (bytes, bytearray, memoryview)):
            return tpe.Sha256(tpe.InputBytes(transaction_hash))

        if isinstance(transaction_hash, tpe.Sha256):
            return transaction_hash

        raise ValueError(
            "Attempted to find cache entry with incorrect key type")
def contents_cleanup(transaction_service: TransactionService,
                     block_confirmation_message: AbstractCleanupMessage,
                     cleanup_tasks
                     ):
    start_datetime = datetime.utcnow()
    start_time = time.time()
    tx_service = typing.cast(ExtensionTransactionService, transaction_service)
    cleanup_task = cleanup_tasks.borrow_task()
    cleanup_task.init(tpe.InputBytes(block_confirmation_message.buf), tx_service.proxy)
    task_pool_proxy.run_task(cleanup_task)
    short_ids = cleanup_task.short_ids()
    total_content_removed = cleanup_task.total_content_removed()
    tx_count = cleanup_task.tx_count()
    message_hash = block_confirmation_message.message_hash()
    tx_service.update_removed_transactions(total_content_removed, short_ids)
    transaction_service.on_block_cleaned_up(message_hash)
    end_datetime = datetime.utcnow()
    end_time = time.time()
    duration = end_time - start_time
    logger.statistics(
        {
            "type": "MemoryCleanup",
            "event": "CacheStateAfterBlockCleanup",
            "data": transaction_service.get_cache_state_json(),
            "start_datetime": start_datetime,
            "end_datetime": end_datetime,
            "duration": duration,
            "total_content_removed": total_content_removed,
            "tx_count": tx_count,
            "short_ids_count": len(short_ids),
            "message_hash": repr(message_hash),
        }
    )
    cleanup_tasks.return_task(cleanup_task)
Ejemplo n.º 4
0
    def block_to_bx_block(
            self, block_msg, tx_service, enable_block_compression: bool,
            min_tx_age_seconds: float) -> Tuple[memoryview, BlockInfo]:
        compress_start_datetime = datetime.utcnow()
        compress_start_timestamp = time.time()
        self._default_block_size = max(self._default_block_size,
                                       len(block_msg.buf))
        tsk = self.compression_tasks.borrow_task()
        tsk.init(tpe.InputBytes(block_msg.buf), tx_service.proxy,
                 enable_block_compression, min_tx_age_seconds)
        try:
            task_pool_proxy.run_task(tsk)
        except tpe.AggregatedException as e:
            self.compression_tasks.return_task(tsk)
            raise message_conversion_error.btc_block_compression_error(
                block_msg.block_hash(), e)
        bx_block = tsk.bx_block()
        block = memoryview(bx_block)
        compressed_size = len(block)
        original_size = len(block_msg.rawbytes())
        block_hash = OntObjectHash(
            binary=convert.hex_to_bytes(tsk.block_hash().hex_string()))

        block_info = BlockInfo(
            block_hash, tsk.short_ids(), compress_start_datetime,
            datetime.utcnow(), (time.time() - compress_start_timestamp) * 1000,
            tsk.txn_count(),
            tsk.compressed_block_hash().hex_string(),
            tsk.prev_block_hash().hex_string(), original_size, compressed_size,
            100 - float(compressed_size) / original_size * 100,
            tsk.ignored_short_ids())
        self.compression_tasks.return_task(tsk)
        return block, block_info
 def track_seen_short_ids(self, block_hash, short_ids: List[int]) -> None:
     start_datetime = datetime.now()
     super(ExtensionTransactionService,
           self).track_seen_short_ids(block_hash, short_ids)
     wrapped_block_hash = tpe.Sha256(
         tpe.InputBytes(self._wrap_sha256(block_hash).binary))
     proxy_start_datetime = datetime.now()
     # TODO when refactoring add `block_hash` to proxy.track_seen_short_ids as first parameter and change ds type in cpp
     result = self.proxy.track_seen_short_ids(wrapped_block_hash,
                                              tpe.UIntList(short_ids))
     removed_contents_size, dup_sids = result
     self.update_removed_transactions(removed_contents_size, dup_sids)
     logger_memory_cleanup.statistics({
         "type":
         "MemoryCleanup",
         "event":
         "ExtensionTransactionServiceTrackSeenSummary",
         "seen_short_ids_count":
         len(short_ids),
         "total_content_size_removed":
         removed_contents_size,
         "total_duplicate_short_ids":
         len(dup_sids),
         "proxy_call_datetime":
         proxy_start_datetime,
         "data":
         self.get_cache_state_json(),
         "start_datetime":
         start_datetime,
         "block_hash":
         repr(block_hash)
     })
Ejemplo n.º 6
0
    def process_transactions_message_from_node(
        self,
        msg,
        min_tx_network_fee: int,
        enable_transaction_validation: bool
    ) -> List[ProcessTransactionMessageFromNodeResult]:
        opts = self.node.opts
        msg_bytes = msg.rawbytes()

        if (isinstance(self.node, OntGatewayNode) or isinstance(self.node, EthGatewayNode)) and \
                opts.process_node_txs_in_extension:
            ext_processing_results = memoryview(self.proxy.process_gateway_transaction_from_node(
                tpe.InputBytes(msg_bytes),
                min_tx_network_fee,
                enable_transaction_validation
            ))
        else:
            return GatewayTransactionService.process_transactions_message_from_node(
                self, msg, min_tx_network_fee, enable_transaction_validation
            )

        result = []

        offset = 0

        txs_count, = struct.unpack_from("<I", ext_processing_results, offset)
        offset += constants.UL_INT_SIZE_IN_BYTES

        while offset < len(ext_processing_results):
            seen, = struct.unpack_from("<?", ext_processing_results, offset)
            offset += 1

            tx_hash = Sha256Hash(ext_processing_results[offset:offset + crypto.SHA256_HASH_LEN])
            offset += crypto.SHA256_HASH_LEN
            tx_offset, = struct.unpack_from("<I", ext_processing_results, offset)
            offset += constants.UL_INT_SIZE_IN_BYTES
            tx_len, = struct.unpack_from("<I", ext_processing_results, offset)
            offset += constants.UL_INT_SIZE_IN_BYTES
            tx_validation_status, = struct.unpack_from("<I", ext_processing_results, offset)
            offset += constants.UL_INT_SIZE_IN_BYTES

            tx_contents = msg_bytes[tx_offset:tx_offset + tx_len]

            result.append(
                ProcessTransactionMessageFromNodeResult(
                    seen,
                    tx_hash,
                    tx_contents,
                    TxMessage(message_hash=tx_hash, network_num=self.network_num, tx_val=tx_contents),
                    TxValidationStatus(tx_validation_status)
                )
            )

            if not seen:
                transaction_cache_key = self._tx_hash_to_cache_key(tx_hash)
                self.set_transaction_contents_base(tx_hash, transaction_cache_key, False, 0, False, tx_contents, tx_len)

        assert txs_count == len(result)

        return result
Ejemplo n.º 7
0
 def compact_block_to_bx_block(
     self, compact_block: CompactBlockBtcMessage,
     transaction_service: ExtensionTransactionService
 ) -> CompactBlockCompressionResult:
     compress_start_datetime = datetime.utcnow()
     tsk = self.compact_mapping_tasks.borrow_task()
     tsk.init(tpe.InputBytes(compact_block.buf), transaction_service.proxy,
              compact_block.magic())
     try:
         task_pool_proxy.run_task(tsk)
     except tpe.AggregatedException as e:
         self.compact_mapping_tasks.return_task(tsk)
         raise message_conversion_error.btc_compact_block_compression_error(
             compact_block.block_hash(), e)
     success = tsk.success()
     recovered_item = ExtensionCompactBlockRecoveryData(
         transaction_service, tsk)
     block_info = BlockInfo(compact_block.block_hash(), [],
                            compress_start_datetime,
                            compress_start_datetime, 0, None, None, None,
                            len(compact_block.rawbytes()), None, None, [])
     if success:
         result = CompactBlockCompressionResult(
             False, block_info, None, None, [],
             create_recovered_transactions())
         return self._extension_recovered_compact_block_to_bx_block(
             result, recovered_item)
     else:
         recovery_index = self._last_recovery_idx
         self._extension_recovered_items[recovery_index] = recovered_item
         self._last_recovery_idx += 1
         return CompactBlockCompressionResult(
             False, block_info, None, recovery_index, tsk.missing_indices(),
             create_recovered_transactions())
Ejemplo n.º 8
0
def run_encryption(plain, et=None):
    if et is None:
        et = tpe.EncryptionTask(len(plain))
    plain_text = tpe.InputBytes(bytearray(plain))
    et.init(plain_text)
    task_pool_proxy.run_task(et)
    return et
Ejemplo n.º 9
0
    def process_gateway_transaction_from_bdn(
            self, transaction_hash: Sha256Hash, short_id: int,
            transaction_contents: Union[bytearray, memoryview],
            is_compact: bool) -> TransactionFromBdnGatewayProcessingResult:

        transaction_key = self.get_transaction_key(transaction_hash)

        ext_result = self.proxy.process_gateway_transaction_from_bdn(
            # pyre-fixme[6]: Expected `bxcommon.models.transaction_key.TransactionKey`
            transaction_key.transaction_cache_key,
            tpe.InputBytes(transaction_contents),
            short_id,
            is_compact)

        result = TransactionFromBdnGatewayProcessingResult(
            ext_result.get_ignore_seen(), ext_result.get_existing_short_id(),
            ext_result.get_assigned_short_id(),
            ext_result.get_existing_contents(), ext_result.get_set_contents())

        if result.set_content:
            has_short_id, previous_size = ext_result.get_set_contents_result()
            self.set_transaction_contents_base_by_key(
                transaction_key, has_short_id, previous_size, False,
                transaction_contents, len(transaction_contents))

        if result.assigned_short_id:
            has_contents = result.existing_contents or result.set_content
            self.assign_short_id_base_by_key(transaction_key, short_id,
                                             has_contents, False)

        return result
Ejemplo n.º 10
0
    def block_to_bx_block(
        self, block_msg: InternalEthBlockInfo,
        tx_service: ExtensionTransactionService
    ) -> Tuple[memoryview, BlockInfo]:
        compress_start_datetime = datetime.datetime.utcnow()
        compress_start_timestamp = time.time()
        self._default_block_size = max(self._default_block_size,
                                       len(block_msg.rawbytes()))
        tsk = self.compression_tasks.borrow_task()
        tsk.init(tpe.InputBytes(block_msg.rawbytes()), tx_service.proxy)
        try:
            task_pool_proxy.run_task(tsk)
        except tpe.AggregatedException as e:
            self.compression_tasks.return_task(tsk)
            raise message_conversion_error.eth_block_compression_error(
                block_msg.block_hash(), e)
        bx_block = tsk.bx_block()
        starting_offset = tsk.starting_offset()
        block = memoryview(bx_block)[starting_offset:]
        compressed_size = len(block)
        original_size = len(block_msg.rawbytes()) - starting_offset
        block_hash = block_msg.block_hash()

        block_info = BlockInfo(
            block_hash, tsk.short_ids(), compress_start_datetime,
            datetime.datetime.utcnow(),
            (time.time() - compress_start_timestamp) * 1000, tsk.txn_count(),
            tsk.compressed_block_hash().hex_string(),
            tsk.prev_block_hash().hex_string(), original_size, compressed_size,
            100 - float(compressed_size) / original_size * 100)
        self.compression_tasks.return_task(tsk)
        return block, block_info
    def process_tx_sync_message(
            self,
            msg: TxServiceSyncTxsMessage) -> List[TxSyncMsgProcessingItem]:
        input_bytes = tpe.InputBytes(msg.rawbytes())
        result_bytes = self.proxy.process_tx_sync_message(input_bytes)

        assert result_bytes is not None
        result_memory_view = memoryview(result_bytes)

        result_items = []
        offset = 0

        txs_count, = struct.unpack_from("<L", result_memory_view, offset)
        offset += constants.UL_INT_SIZE_IN_BYTES

        for _ in range(txs_count):
            transaction_hash = Sha256Hash(
                result_memory_view[offset:offset + crypto.SHA256_HASH_LEN])
            transaction_key = self.get_transaction_key(transaction_hash)
            offset += crypto.SHA256_HASH_LEN

            content_len, = struct.unpack_from("<L", result_memory_view, offset)
            offset += constants.UL_INT_SIZE_IN_BYTES

            short_id_count, = struct.unpack_from("<L", result_memory_view,
                                                 offset)
            offset += constants.UL_INT_SIZE_IN_BYTES

            if content_len > 0:
                self.set_transaction_contents_base_by_key(
                    transaction_key, short_id_count > 0, 0, False, None,
                    content_len)

            short_ids = []

            for _ in range(short_id_count):
                short_id, = struct.unpack_from("<L", result_memory_view,
                                               offset)
                offset += constants.UL_INT_SIZE_IN_BYTES

                self.assign_short_id_base_by_key(transaction_key, short_id,
                                                 content_len > 0, False)

                short_ids.append(short_id)

            transaction_flags = []

            for _ in range(short_id_count):
                transaction_flag, = struct.unpack_from("<H",
                                                       result_memory_view,
                                                       offset)
                offset += constants.TRANSACTION_FLAG_LEN
                transaction_flags.append(TransactionFlag(transaction_flag))

            result_items.append(
                TxSyncMsgProcessingItem(transaction_hash, content_len,
                                        short_ids, transaction_flags))

        return result_items
    def clean_block_transactions(
            self, block_msg: BlockBtcMessage, transaction_service: TransactionService
    ) -> None:
        start_datetime = datetime.utcnow()
        start_time = time.time()
        tx_hash_to_contents_len_before_cleanup = transaction_service.get_tx_hash_to_contents_len()
        cleanup_task = self.block_cleanup_tasks.borrow_task()
        tx_service = typing.cast(ExtensionTransactionService, transaction_service)
        cleanup_task.init(tpe.InputBytes(block_msg.buf), tx_service.proxy)
        init_time = time.time()
        task_pool_proxy.run_task(cleanup_task)
        task_run_time = time.time()
        unknown_tx_hashes_count = len(cleanup_task.unknown_tx_hashes())
        tx_property_fetch_time = time.time()
        short_ids = cleanup_task.short_ids()
        short_ids_fetch_time = time.time()
        short_ids_count = len(short_ids)
        tx_service.update_removed_transactions(cleanup_task.total_content_removed(), short_ids)
        remove_from_tx_service_time = time.time()
        # TODO : clean the short ids/transactions from the alarm queue after refactoring the transaction service
        block_hash = block_msg.block_hash()
        tx_service.on_block_cleaned_up(block_hash)
        tx_hash_to_contents_len_after_cleanup = transaction_service.get_tx_hash_to_contents_len()
        end_datetime = datetime.utcnow()
        end_time = time.time()

        logger.statistics(
            {
                "type": "BlockTransactionsCleanup",
                "block_hash": repr(block_hash),
                "unknown_tx_hashes_count": unknown_tx_hashes_count,
                "short_ids_count": short_ids_count,
                "block_transactions_count": cleanup_task.txn_count(),
                "start_datetime": start_datetime,
                "end_datetime": end_datetime,
                "task_init_time": init_time - start_time,
                "task_run_time": task_run_time - init_time,
                "tx_property_fetch_time": tx_property_fetch_time - task_run_time,
                "short_ids_fetch_time": short_ids_fetch_time - tx_property_fetch_time,
                "remove_from_tx_service_time": remove_from_tx_service_time - short_ids_fetch_time,
                "duration": end_time - start_time,
                "tx_hash_to_contents_len_before_cleanup": tx_hash_to_contents_len_before_cleanup,
                "tx_hash_to_contents_len_after_cleanup": tx_hash_to_contents_len_after_cleanup,
            }
        )
        self.block_cleanup_tasks.return_task(cleanup_task)
        self._block_hash_marked_for_cleanup.discard(block_hash)
        self.node.post_block_cleanup_tasks(
            block_hash=block_hash,
            short_ids=short_ids,
            unknown_tx_hashes=(
                Sha256Hash(convert.hex_to_bytes(tx_hash.hex_string()))
                for tx_hash in cleanup_task.unknown_tx_hashes()
            )
        )
    def get_transactions(
        self,
        serialized_short_ids: Optional[bytearray] = None
    ) -> TransactionSearchResult:
        """
        Fetches all transaction info for a set of short ids.
        Short ids without a transaction entry will be omitted.
        Function allows to pass a single short id or serialized list of short ids
        :param serialized_short_ids: instance of get transactions message
        :return: list of found and missing short ids
        """

        assert serialized_short_ids is not None
        input_bytes = tpe.InputBytes(serialized_short_ids)

        result_bytes = self.proxy.get_transactions_by_short_ids(input_bytes)
        assert result_bytes is not None
        result_memory_view = memoryview(result_bytes)

        found_txs_size, = struct.unpack_from("<L", result_memory_view, 0)

        txs_bytes = result_memory_view[constants.UL_INT_SIZE_IN_BYTES:constants
                                       .UL_INT_SIZE_IN_BYTES + found_txs_size]
        found_txs_info = transactions_info_serializer \
            .deserialize_transactions_info(txs_bytes)

        missing_txs_info = []
        offset = constants.UL_INT_SIZE_IN_BYTES + found_txs_size

        missing_txs_count, = struct.unpack_from("<L", result_memory_view,
                                                offset)
        offset += constants.UL_INT_SIZE_IN_BYTES

        for _ in range(missing_txs_count):
            tx_sid, = struct.unpack_from("<L", result_memory_view, offset)
            offset += constants.UL_INT_SIZE_IN_BYTES

            has_hash, = struct.unpack_from("<B", result_memory_view, offset)
            offset += constants.UL_TINY_SIZE_IN_BYTES

            if has_hash:
                tx_hash = Sha256Hash(
                    result_memory_view[offset:offset + crypto.SHA256_HASH_LEN])
                offset += crypto.SHA256_HASH_LEN
            else:
                tx_hash = None

            missing_txs_info.append(TransactionInfo(tx_hash, None, tx_sid))

        return TransactionSearchResult(found_txs_info, missing_txs_info)
Ejemplo n.º 14
0
 def __init__(self, node, network_num):
     super(ExtensionTransactionService, self).__init__(node, network_num)
     self.proxy = tpe.TransactionService(
         task_pool_proxy.get_pool_size(), node.opts.tx_mem_pool_bucket_size,
         self._get_final_tx_confirmations_count())
     raw_encoder = ObjectEncoder.raw_encoder()
     self._tx_cache_key_to_short_ids = DefaultMapProxy(
         self.proxy.tx_hash_to_short_ids(), raw_encoder, raw_encoder)
     self._short_id_to_tx_cache_key = MapProxy(
         self.proxy.short_id_to_tx_hash(), raw_encoder, raw_encoder)
     content_encoder = ObjectEncoder(lambda buf_view: memoryview(buf_view),
                                     lambda buf: tpe.InputBytes(buf))
     self._tx_cache_key_to_contents = MapProxy(
         self.proxy.tx_hash_to_contents(), raw_encoder, content_encoder)
     self._tx_not_seen_in_blocks = self.proxy.tx_not_seen_in_blocks()
 def bx_block_to_block(self, bx_block_msg, tx_service) -> BlockDecompressionResult:
     decompress_start_datetime = datetime.utcnow()
     decompress_start_timestamp = time.time()
     tsk = self.decompression_tasks.borrow_task()
     tsk.init(tpe.InputBytes(bx_block_msg), tx_service.proxy)
     try:
         task_pool_proxy.run_task(tsk)
     except tpe.AggregatedException as e:
         self.decompression_tasks.return_task(tsk)
         header_info = btc_normal_message_converter.parse_bx_block_header(bx_block_msg, deque())
         raise message_conversion_error.btc_block_decompression_error(header_info.block_hash, e)
     total_tx_count = tsk.tx_count()
     unknown_tx_hashes = [Sha256Hash(bytearray(unknown_tx_hash.binary()))
                          for unknown_tx_hash in tsk.unknown_tx_hashes()]
     unknown_tx_sids = tsk.unknown_tx_sids()
     block_hash = BtcObjectHash(
         binary=convert.hex_to_bytes(tsk.block_hash().hex_string())
     )
     if tsk.success():
         btc_block_msg = BlockBtcMessage(buf=memoryview(tsk.block_message()))
         logger.debug(
             "Successfully parsed block broadcast message. {} transactions "
             "in block {}",
             total_tx_count,
             block_hash
         )
     else:
         btc_block_msg = None
         logger.debug(
             "Block recovery needed for {}. Missing {} sids, {} tx hashes. "
             "Total txs in block: {}",
             block_hash,
             len(unknown_tx_sids),
             len(unknown_tx_hashes),
             total_tx_count
         )
     block_info = get_block_info(
         bx_block_msg,
         block_hash,
         tsk.short_ids(),
         decompress_start_datetime,
         decompress_start_timestamp,
         total_tx_count,
         btc_block_msg
     )
     self.decompression_tasks.return_task(tsk)
     return BlockDecompressionResult(btc_block_msg, block_info, unknown_tx_sids, unknown_tx_hashes)
    def set_transaction_contents_by_key(
            self, transaction_key: TransactionKey,
            transaction_contents: Union[bytearray, memoryview]):
        """
        Adds transaction contents to transaction service cache with lookup key by transaction hash

        :param transaction_key: transaction key object
        :param transaction_contents: transaction contents bytes
        """
        has_short_id, previous_size = self.proxy.set_transaction_contents(
            # pyre-fixme[6]: Expected `tpe.Sha256` got `TransactionCacheKeyType`.
            transaction_key.transaction_cache_key,
            tpe.InputBytes(transaction_contents))

        self.set_transaction_contents_base_by_key(transaction_key,
                                                  has_short_id, previous_size,
                                                  False, transaction_contents,
                                                  len(transaction_contents))
Ejemplo n.º 17
0
    def process_txs_message(
        self,
        msg: TxsMessage
    ) -> Set[MissingTransactions]:
        msg_bytes = msg.rawbytes()
        missing_transactions: Set[MissingTransactions] = set()
        result_buffer = memoryview(self.proxy.process_txs_msg(tpe.InputBytes(msg_bytes)))
        # result_buffer is a bytearray that consists of
        # number of missing transactions - 2 bytes
        # a list of:
        #   short_id - 4 bytes
        #   Sha256Hash - 32 bytes
        #   content length that was added to transaction service - 4 bytes
        offset = 0
        missing_transactions_count, = struct.unpack_from("<H", result_buffer, offset)
        offset += constants.UL_SHORT_SIZE_IN_BYTES
        if missing_transactions_count == 0:
            return missing_transactions

        while offset < len(result_buffer):
            short_id, = struct.unpack_from("<L", result_buffer, offset)
            offset += constants.SID_LEN

            transaction_hash = Sha256Hash(result_buffer[offset:offset + crypto.SHA256_HASH_LEN])
            offset += crypto.SHA256_HASH_LEN

            content_length, = struct.unpack_from("<L", result_buffer, offset)
            offset += constants.UL_INT_SIZE_IN_BYTES
            if content_length > 0:
                self.set_transaction_contents_base(
                    transaction_hash,
                    transaction_hash,
                    True,
                    0,
                    False,
                    None,
                    content_length
                )
            missing_transactions.add(MissingTransactions(short_id, transaction_hash))

        return missing_transactions
def create_recovered_transactions() -> VectorProxy[tpe.InputBytes, memoryview]:
    encoder = ObjectEncoder(
        lambda input_bytes: memoryview(input_bytes), lambda buf: tpe.InputBytes(buf)
    )
    return VectorProxy(tpe.TransactionList(), encoder)
Ejemplo n.º 19
0
    def bx_block_to_block(self, bx_block_msg,
                          tx_service) -> BlockDecompressionResult:
        decompress_start_datetime = datetime.datetime.utcnow()
        decompress_start_timestamp = time.time()
        tsk = self.decompression_tasks.borrow_task()
        tsk.init(tpe.InputBytes(bx_block_msg), tx_service.proxy)
        try:
            task_pool_proxy.run_task(tsk)
        except tpe.AggregatedException as e:
            block_hash = Sha256Hash(
                convert.hex_to_bytes(tsk.block_hash().hex_string()))
            self.decompression_tasks.return_task(tsk)
            # TODO find a better solution
            raise message_conversion_error.eth_block_decompression_error(
                block_hash, e)

        total_tx_count = tsk.tx_count()
        unknown_tx_hashes = [
            Sha256Hash(bytearray(unknown_tx_hash.binary()))
            for unknown_tx_hash in tsk.unknown_tx_hashes()
        ]
        unknown_tx_sids = tsk.unknown_tx_sids()
        block_hash = Sha256Hash(
            convert.hex_to_bytes(tsk.block_hash().hex_string()))

        if tsk.success():
            starting_offset = tsk.starting_offset()
            block = memoryview(tsk.block_message())[starting_offset:]
            block_msg = InternalEthBlockInfo(block)
            content_size = len(block_msg.rawbytes())
            logger.debug(
                "Successfully parsed block broadcast message. {} "
                "transactions in block {}", total_tx_count, block_hash)
            bx_block_hash = convert.bytes_to_hex(
                crypto.double_sha256(bx_block_msg))
            compressed_size = len(bx_block_msg)

            block_info = BlockInfo(
                block_hash, tsk.short_ids(), decompress_start_datetime,
                datetime.datetime.utcnow(),
                (time.time() - decompress_start_timestamp) * 1000,
                total_tx_count, bx_block_hash,
                convert.bytes_to_hex(block_msg.prev_block_hash().binary),
                len(block_msg.rawbytes()), compressed_size,
                100 - float(compressed_size) / content_size * 100)
        else:
            block_msg = None

            logger.debug(
                "Block recovery needed for {}. Missing {} sids, {} tx hashes. "
                "Total txs in block: {}", block_hash, len(unknown_tx_sids),
                len(unknown_tx_hashes), total_tx_count)
            block_info = BlockInfo(
                block_hash, tsk.short_ids(), decompress_start_datetime,
                datetime.datetime.utcnow(),
                (time.time() - decompress_start_timestamp) * 1000, None, None,
                None, None, None, None)

        self.decompression_tasks.return_task(tsk)
        return BlockDecompressionResult(block_msg, block_info, unknown_tx_sids,
                                        unknown_tx_hashes)
Ejemplo n.º 20
0
 def on_block_cleaned_up(self, block_hash: Sha256Hash) -> None:
     super(ExtensionTransactionService,
           self).on_block_cleaned_up(block_hash)
     wrapped_block_hash = tpe.Sha256(tpe.InputBytes(block_hash.binary))
     self.proxy.on_block_cleaned_up(wrapped_block_hash)
Ejemplo n.º 21
0
 def test_encode_sha256_tpe(self):
     hash_ = "96e900d13d89eb12219e18ddc7aae8ec173a3cff196f09556b5d730df4a10732"
     items = [tpe.Sha256(tpe.InputBytes(convert.hex_to_bytes(hash_)))]
     js = json.dumps(items, cls=EnhancedJSONEncoder)
     self.assertEqual(json.loads(js), [hash_])