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 parse_bx_block_transactions_and_msg_tail(block_hash: Sha256Hash, bx_block: memoryview, offset: int, short_ids: List[int], block_offsets: BlockOffsets, tx_service: TransactionService, block_pieces: Deque[Union[bytearray, memoryview]]) -> \ Tuple[List[int], List[Sha256Hash], int]: has_missing, unknown_tx_sids, unknown_tx_hashes = tx_service.get_missing_transactions(short_ids) if has_missing: return unknown_tx_sids, unknown_tx_hashes, offset short_tx_index = 0 output_offset = offset while offset < block_offsets.short_id_offset: if bx_block[offset] == ont_constants.ONT_SHORT_ID_INDICATOR: try: sid = short_ids[short_tx_index] except IndexError: raise message_conversion_error.btc_block_decompression_error( block_hash, f"Message is improperly formatted, short id index ({short_tx_index}) " f"exceeded its array bounds (size: {len(short_ids)})" ) tx_hash, tx, _ = tx_service.get_transaction(sid) offset += ont_constants.ONT_SHORT_ID_INDICATOR_LENGTH short_tx_index += 1 else: tx_size = ont_messages_util.get_next_tx_size(bx_block, offset) tx = bx_block[offset:offset + tx_size] offset += tx_size assert tx is not None block_pieces.append(tx) output_offset += len(tx) # Add consensus payload tail and owner and signature to block_pieces offset = block_offsets.block_begin_offset + ont_constants.ONT_HASH_LEN + ont_constants.ONT_INT_LEN + 1 payload_tail_len, = struct.unpack_from("<L", bx_block, offset) offset += ont_constants.ONT_INT_LEN block_pieces.append(bx_block[offset: offset + payload_tail_len]) offset += payload_tail_len owner_and_signature_len, = struct.unpack_from("<L", bx_block, offset) offset += ont_constants.ONT_INT_LEN block_pieces.append(bx_block[offset: offset + owner_and_signature_len]) offset += owner_and_signature_len return unknown_tx_sids, unknown_tx_hashes, output_offset
def parse_bx_block_transactions( block_hash: Sha256Hash, bx_block: memoryview, offset: int, short_ids: List[int], block_offsets: BlockOffsets, tx_service: TransactionService, block_pieces: Deque[Union[bytearray, memoryview]] ) -> Tuple[List[int], List[Sha256Hash], int]: has_missing, unknown_tx_sids, unknown_tx_hashes = \ tx_service.get_missing_transactions(short_ids) if has_missing: return unknown_tx_sids, unknown_tx_hashes, offset short_tx_index = 0 output_offset = offset while offset < block_offsets.short_id_offset: if bx_block[offset] == btc_constants.BTC_SHORT_ID_INDICATOR: try: sid = short_ids[short_tx_index] except IndexError: raise message_conversion_error.btc_block_decompression_error( block_hash, f"Message is improperly formatted, short id index ({short_tx_index}) " f"exceeded its array bounds (size: {len(short_ids)})" ) tx_hash, tx, _ = tx_service.get_transaction(sid) offset += btc_constants.BTC_SHORT_ID_INDICATOR_LENGTH short_tx_index += 1 else: tx_size = btc_messages_util.get_next_tx_size(bx_block, offset) tx = bx_block[offset:offset + tx_size] offset += tx_size # pyre-fixme[6]: Expected `Union[bytearray, memoryview]` for 1st param but # got `Optional[Union[bytearray, memoryview]]`. block_pieces.append(tx) # pyre-fixme[6]: Expected `Sized` for 1st param but got # `Optional[Union[bytearray, memoryview]]`. output_offset += len(tx) return unknown_tx_sids, unknown_tx_hashes, output_offset