def create_txs_service_msg( transaction_service: TransactionService, tx_service_snap: List[Sha256Hash], sync_tx_content: bool = True) -> List[TxContentShortIds]: task_start = time.time() txs_content_short_ids: List[TxContentShortIds] = [] txs_msg_len = 0 while tx_service_snap: transaction_key = transaction_service.get_transaction_key( tx_service_snap.pop()) short_ids = list( transaction_service.get_short_ids_by_key(transaction_key)) if sync_tx_content: tx_content = transaction_service.get_transaction_by_key( transaction_key) else: tx_content = bytearray(0) # TODO: evaluate short id quota type flag value short_id_flags = [ transaction_service.get_short_id_transaction_type(short_id) for short_id in short_ids ] tx_content_short_ids: TxContentShortIds = TxContentShortIds( transaction_key.transaction_hash, tx_content, short_ids, short_id_flags) txs_msg_len += txs_serializer.get_serialized_tx_content_short_ids_bytes_len( tx_content_short_ids) txs_content_short_ids.append(tx_content_short_ids) if txs_msg_len >= constants.TXS_MSG_SIZE or time.time( ) - task_start > constants.TXS_SYNC_TASK_DURATION: break return txs_content_short_ids
def compact_block_to_bx_block( self, compact_block: CompactBlockBtcMessage, transaction_service: TransactionService ) -> CompactBlockCompressionResult: """ Handle decompression of Bitcoin compact block. Decompression converts compact block message to full block message. """ compress_start_datetime = datetime.utcnow() block_header = compact_block.block_header() sha256_hash = hashlib.sha256() sha256_hash.update(block_header) sha256_hash.update(compact_block.short_nonce_buf()) hex_digest = sha256_hash.digest() key = hex_digest[0:16] short_ids = compact_block.short_ids() short_id_to_tx_contents = {} for tx_hash in transaction_service.iter_transaction_hashes(): transaction_key = transaction_service.get_transaction_key(tx_hash) tx_hash_binary = tx_hash.binary[::-1] tx_short_id = compute_short_id(key, tx_hash_binary) if tx_short_id in short_ids: tx_content = transaction_service.get_transaction_by_key( transaction_key) if tx_content is None: logger.debug( "Hash {} is known by transactions service but content is missing.", tx_hash) else: short_id_to_tx_contents[tx_short_id] = tx_content if len(short_id_to_tx_contents) == len(short_ids): break block_transactions = [] missing_transactions_indices = [] pre_filled_transactions = compact_block.pre_filled_transactions() total_txs_count = len(pre_filled_transactions) + len(short_ids) size = 0 block_msg_parts = deque() block_msg_parts.append(block_header) size += len(block_header) tx_count_size = btc_messages_util.get_sizeof_btc_varint( total_txs_count) tx_count_buf = bytearray(tx_count_size) btc_messages_util.pack_int_to_btc_varint(total_txs_count, tx_count_buf, 0) block_msg_parts.append(tx_count_buf) size += tx_count_size short_ids_iter = iter(short_ids.keys()) for index in range(total_txs_count): if index not in pre_filled_transactions: short_id = next(short_ids_iter) if short_id in short_id_to_tx_contents: short_tx = short_id_to_tx_contents[short_id] block_msg_parts.append(short_tx) block_transactions.append(short_tx) size += len(short_tx) else: missing_transactions_indices.append(index) block_transactions.append(None) else: pre_filled_transaction = pre_filled_transactions[index] block_msg_parts.append(pre_filled_transaction) block_transactions.append(pre_filled_transaction) size += len(pre_filled_transaction) recovered_item = CompactBlockRecoveryData(block_transactions, block_header, compact_block.magic(), transaction_service) block_info = BlockInfo(compact_block.block_hash(), [], compress_start_datetime, compress_start_datetime, 0, None, None, None, len(compact_block.rawbytes()), None, None, []) if len(missing_transactions_indices) > 0: recovery_index = self._last_recovery_idx self._last_recovery_idx += 1 self._recovery_items[ recovery_index] = recovered_item # pyre-ignore return CompactBlockCompressionResult(False, block_info, None, recovery_index, missing_transactions_indices, []) result = CompactBlockCompressionResult(False, block_info, None, None, [], []) return self._recovered_compact_block_to_bx_block( result, recovered_item)