def test_block_headers_request(self): get_headers = GetBlockHeadersEthProtocolMessage(None, self.BLOCK_HASH, 111, 222, 0) # Reply with empty headers to the first get headers request for fast sync mode support get_headers_frames = map(self.eth_node_cipher.encrypt_frame, frame_utils.get_frames(get_headers.msg_type, get_headers.rawbytes())) for get_headers_frame in get_headers_frames: helpers.receive_node_message(self.gateway_node, self.local_node_fileno, get_headers_frame) self.eth_remote_node_connection.enqueue_msg.assert_not_called() self.eth_node_connection.enqueue_msg.assert_called_once_with(BlockHeadersEthProtocolMessage(None, [])) # The second get headers message should be proxied to remote blockchain node get_headers_frames = map(self.eth_node_cipher.encrypt_frame, frame_utils.get_frames(get_headers.msg_type, get_headers.rawbytes())) for get_headers_frame in get_headers_frames: helpers.receive_node_message(self.gateway_node, self.local_node_fileno, get_headers_frame) self.eth_remote_node_connection.enqueue_msg.assert_called_once_with(get_headers) headers = BlockHeadersEthProtocolMessage(None, [ mock_eth_messages.get_dummy_block_header(1), mock_eth_messages.get_dummy_block_header(2) ]) headers_frames = map(self.eth_node_cipher.encrypt_frame, frame_utils.get_frames(headers.msg_type, headers.rawbytes())) for headers_frame in headers_frames: helpers.receive_node_message(self.gateway_node, self.remote_node_fileno, headers_frame) self.eth_node_connection.enqueue_msg.assert_called_with(headers)
def test_block_bodies_msg_from_bodies_bytes(self): txs = [] txs_bytes = [] txs_hashes = [] tx_count = 10 for i in range(1, tx_count): tx = mock_eth_messages.get_dummy_transaction(1) txs.append(tx) tx_bytes = rlp.encode(tx, Transaction) txs_bytes.append(tx_bytes) tx_hash = tx.hash() txs_hashes.append(tx_hash) uncles = [ mock_eth_messages.get_dummy_block_header(2), mock_eth_messages.get_dummy_block_header(3), ] block_body = TransientBlockBody(txs, uncles) block_body_bytes = memoryview( rlp.encode(TransientBlockBody.serialize(block_body))) block_bodies_msg = BlockBodiesEthProtocolMessage.from_body_bytes( block_body_bytes) self.assertEqual(1, len(block_bodies_msg.get_blocks())) self.assertEqual(1, len(block_bodies_msg.get_block_bodies_bytes())) self.assertEqual(block_body, block_bodies_msg.get_blocks()[0]) self.assertEqual(block_body_bytes, block_bodies_msg.get_block_bodies_bytes()[0])
def test_block_header_eth_message(self): self._test_msg_serialization( BlockHeadersEthProtocolMessage, False, [ mock_eth_messages.get_dummy_block_header(1), mock_eth_messages.get_dummy_block_header(2), mock_eth_messages.get_dummy_block_header(3), ], )
def test_new_block_parts_to_new_block_message(self): txs = [] txs_bytes = [] txs_hashes = [] tx_count = 10 for i in range(1, tx_count): tx = mock_eth_messages.get_dummy_transaction(1) txs.append(tx) tx_bytes = rlp.encode(tx, Transaction) txs_bytes.append(tx_bytes) tx_hash = tx.hash() txs_hashes.append(tx_hash) block_header = mock_eth_messages.get_dummy_block_header(1) uncles = [ mock_eth_messages.get_dummy_block_header(2), mock_eth_messages.get_dummy_block_header(3), ] block = Block(block_header, txs, uncles) dummy_chain_difficulty = 10 new_block_msg = NewBlockEthProtocolMessage(None, block, dummy_chain_difficulty) self.assertTrue(new_block_msg.rawbytes()) block_body = TransientBlockBody(txs, uncles) block_bytes = rlp.encode(Block.serialize(block)) block_header_bytes = memoryview( rlp.encode(BlockHeader.serialize(block_header))) block_body_bytes = memoryview( rlp.encode(TransientBlockBody.serialize(block_body))) self.assertEqual(len(block_bytes), len(block_header_bytes) + len(block_body_bytes)) internal_new_block_msg = InternalEthBlockInfo.from_new_block_msg( new_block_msg) new_block_parts = internal_new_block_msg.to_new_block_parts() new_block_msg_from_block_parts = NewBlockEthProtocolMessage.from_new_block_parts( new_block_parts, dummy_chain_difficulty) self.assertEqual(len(new_block_msg.rawbytes()), len(new_block_msg_from_block_parts.rawbytes())) self.assertEqual(new_block_msg.rawbytes(), new_block_msg_from_block_parts.rawbytes()) self.assertEqual(new_block_msg_from_block_parts.get_chain_difficulty(), dummy_chain_difficulty)
def test_block_to_bx_block_then_bx_block_to_block__success(self): txs = [] txs_bytes = [] txs_hashes = [] short_ids = [] tx_count = 150 for i in range(1, tx_count): tx = mock_eth_messages.get_dummy_transaction(i) txs.append(tx) tx_bytes = rlp.encode(tx, Transaction) txs_bytes.append(tx_bytes) tx_hash = tx.hash() txs_hashes.append(tx_hash) self.tx_service.assign_short_id(tx_hash, i) self.tx_service.set_transaction_contents(tx_hash, tx_bytes) short_ids.append(i) block = Block(mock_eth_messages.get_dummy_block_header(100), txs, [mock_eth_messages.get_dummy_block_header(2)]) dummy_chain_difficulty = 40000000 block_msg = NewBlockEthProtocolMessage(None, block, dummy_chain_difficulty) block_msg_bytes = block_msg.rawbytes() self.assertTrue(block_msg_bytes) internal_new_block_msg = InternalEthBlockInfo.from_new_block_msg( block_msg) bx_block_msg, block_info = self.eth_message_converter.block_to_bx_block( internal_new_block_msg, self.tx_service, True, 0) self.assertIsNotNone(bx_block_msg) self.assertEqual(len(txs), block_info.txn_count) self.assertEqual(convert.bytes_to_hex(block.header.prev_hash), block_info.prev_block_hash) converted_block_msg, _, _, _ = self.eth_message_converter.bx_block_to_block( bx_block_msg, self.tx_service) self.assertIsNotNone(converted_block_msg) converted_new_block_msg = converted_block_msg.to_new_block_msg() converted_block_msg_bytes = converted_new_block_msg.rawbytes() self.assertEqual(len(converted_block_msg_bytes), len(block_msg_bytes)) self.assertEqual(converted_block_msg_bytes, block_msg_bytes)
def test_new_block_internal_eth_message_to_from_new_block_parts(self): txs = [] txs_bytes = [] txs_hashes = [] tx_count = 10 for i in range(1, tx_count): tx = mock_eth_messages.get_dummy_transaction(1) txs.append(tx) tx_bytes = rlp.encode(tx, Transaction) txs_bytes.append(tx_bytes) tx_hash = tx.hash() txs_hashes.append(tx_hash) block_header = mock_eth_messages.get_dummy_block_header(1) uncles = [ mock_eth_messages.get_dummy_block_header(2), mock_eth_messages.get_dummy_block_header(3), ] block_number = 100000 block_body = TransientBlockBody(txs, uncles) block_header_bytes = memoryview( rlp.encode(BlockHeader.serialize(block_header))) block_body_bytes = memoryview( rlp.encode(TransientBlockBody.serialize(block_body))) new_block_parts = NewBlockParts(block_header_bytes, block_body_bytes, block_number) new_block_internal_eth_msg = InternalEthBlockInfo.from_new_block_parts( new_block_parts) self.assertIsNotNone(new_block_internal_eth_msg) self.assertTrue(new_block_internal_eth_msg.rawbytes()) parsed_new_block_parts = new_block_internal_eth_msg.to_new_block_parts( ) self.assertIsInstance(parsed_new_block_parts, NewBlockParts) self.assertEqual(block_header_bytes, parsed_new_block_parts.block_header_bytes) self.assertEqual(block_body_bytes, parsed_new_block_parts.block_body_bytes) self.assertEqual(block_number, parsed_new_block_parts.block_number)
def test_new_block_internal_eth_message_to_from_new_block_message(self): txs = [] txs_bytes = [] txs_hashes = [] tx_count = 10 for i in range(1, tx_count): tx = mock_eth_messages.get_dummy_transaction(1) txs.append(tx) tx_bytes = rlp.encode(tx, Transaction) txs_bytes.append(tx_bytes) tx_hash = tx.hash() txs_hashes.append(tx_hash) block_header = mock_eth_messages.get_dummy_block_header(1) uncles = [ mock_eth_messages.get_dummy_block_header(2), mock_eth_messages.get_dummy_block_header(3), ] block = Block(block_header, txs, uncles) dummy_chain_difficulty = 10 block_msg = NewBlockEthProtocolMessage(None, block, dummy_chain_difficulty) self.assertTrue(block_msg.rawbytes()) new_block_internal_eth_msg = InternalEthBlockInfo.from_new_block_msg( block_msg) self.assertIsNotNone(new_block_internal_eth_msg) self.assertTrue(new_block_internal_eth_msg.rawbytes()) parsed_new_block_message = new_block_internal_eth_msg.to_new_block_msg( ) self.assertIsInstance(parsed_new_block_message, NewBlockEthProtocolMessage) self.assertEqual(len(block_msg.rawbytes()), len(parsed_new_block_message.rawbytes())) self.assertEqual( convert.bytes_to_hex(block_msg.rawbytes()), convert.bytes_to_hex(parsed_new_block_message.rawbytes()), )
def test_msg_get_block_headers_known_single(self): header = mock_eth_messages.get_dummy_block_header(12) block = mock_eth_messages.get_dummy_block(1, header) raw_hash = header.hash() block_hash = header.hash_object() new_block_message = NewBlockEthProtocolMessage(None, block, 10) eth_block_info = InternalEthBlockInfo.from_new_block_msg( new_block_message ) self.node.block_queuing_service_manager.push(block_hash, eth_block_info) self.enqueued_messages.clear() self.sut.msg_proxy_request = MagicMock() message = GetBlockHeadersEthProtocolMessage(None, raw_hash, 1, 0, 0) self.sut.msg_get_block_headers(message) self.sut.msg_proxy_request.assert_not_called() self.assertEqual(1, len(self.enqueued_messages)) headers_sent = self.enqueued_messages[0] self.assertIsInstance(headers_sent, BlockHeadersEthProtocolMessage) self.assertEqual(1, len(headers_sent.get_block_headers())) self.assertEqual( block_hash, headers_sent.get_block_headers()[0].hash_object() ) self.block_queuing_service.mark_block_seen_by_blockchain_node( block_hash, eth_block_info ) self.sut.msg_get_block_headers(message) self.sut.msg_proxy_request.assert_not_called() self.assertEqual(2, len(self.enqueued_messages))
def test_msg_get_block_headers_block_number(self): block_number = 123456 header = mock_eth_messages.get_dummy_block_header( 12, block_number=block_number ) block = mock_eth_messages.get_dummy_block(1, header) block_hash = header.hash_object() new_block_message = NewBlockEthProtocolMessage(None, block, 10) eth_block_info = InternalEthBlockInfo.from_new_block_msg( new_block_message ) self.node.block_queuing_service_manager.push(block_hash, eth_block_info) self.enqueued_messages.clear() self.sut.msg_proxy_request = MagicMock() block_number_bytes = struct.pack(">I", block_number) message = GetBlockHeadersEthProtocolMessage( None, block_number_bytes, 1, 0, 0 ) self.sut.msg_get_block_headers(message) self.sut.msg_proxy_request.assert_not_called() self.assertEqual(1, len(self.enqueued_messages)) headers_sent = self.enqueued_messages[0] self.assertIsInstance(headers_sent, BlockHeadersEthProtocolMessage) self.assertEqual(1, len(headers_sent.get_block_headers())) self.assertEqual( block_hash, headers_sent.get_block_headers()[0].hash_object() )
def test_block_to_bx_block__empty_block_success(self): block = Block(mock_eth_messages.get_dummy_block_header(8), [], []) dummy_chain_difficulty = 10 block_msg = NewBlockEthProtocolMessage(None, block, dummy_chain_difficulty) self.assertTrue(block_msg.rawbytes()) internal_new_block_msg = InternalEthBlockInfo.from_new_block_msg(block_msg) bx_block_msg, block_info = self.eth_message_converter.block_to_bx_block( internal_new_block_msg, self.tx_service, True, 0 ) self.assertEqual(0, block_info.txn_count) self.assertEqual(convert.bytes_to_hex(block.header.prev_hash), block_info.prev_block_hash) self.assertTrue(bx_block_msg) self.assertIsInstance(bx_block_msg, memoryview) block_offsets = compact_block_short_ids_serializer.get_bx_block_offsets(bx_block_msg) _, short_ids_len = compact_block_short_ids_serializer.deserialize_short_ids_from_buffer( bx_block_msg, block_offsets.short_id_offset ) compact_block = rlp.decode( bx_block_msg[block_offsets.block_begin_offset: block_offsets.short_id_offset].tobytes(), CompactBlock ) self.assertTrue(compact_block) self.assertIsInstance(compact_block, CompactBlock) self._assert_values_equal(compact_block.header, block.header) self.assertEqual(0, len(compact_block.uncles)) self.assertEqual(0, len(compact_block.transactions)) self.assertEqual(compact_block.chain_difficulty, block_msg.chain_difficulty)
def test_complete_header_body_recovery(self): self.node.block_processing_service.queue_block_for_processing = MagicMock() self.node.block_queuing_service_manager.push = MagicMock() self.node.on_block_seen_by_blockchain_node = MagicMock(return_value=False) self.sut.is_valid_block_timestamp = MagicMock(return_value=True) header = mock_eth_messages.get_dummy_block_header(1) block = mock_eth_messages.get_dummy_block(1, header) block_hash = header.hash_object() new_block_hashes_message = NewBlockHashesEthProtocolMessage.from_block_hash_number_pair( block_hash, 1 ) header_message = BlockHeadersEthProtocolMessage(None, [header]) bodies_message = BlockBodiesEthProtocolMessage(None, [TransientBlockBody(block.transactions, block.uncles)]) self.sut.msg_new_block_hashes(new_block_hashes_message) self.node.on_block_seen_by_blockchain_node.assert_called_once() self.assertEqual(1, len(self.sut.pending_new_block_parts.contents)) self.assertEqual(2, len(self.enqueued_messages)) self.node.on_block_seen_by_blockchain_node.reset_mock() self.node.on_block_seen_by_blockchain_node = MagicMock(return_value=True) self.sut.msg_block_headers(header_message) self.sut.msg_block_bodies(bodies_message) self.assertEqual(1, len(gateway_bdn_performance_stats_service.interval_data.blockchain_node_to_bdn_stats)) for stats in gateway_bdn_performance_stats_service.interval_data.blockchain_node_to_bdn_stats.values(): self.assertEqual(1, stats.new_blocks_received_from_blockchain_node) self.assertEqual(0, stats.new_blocks_received_from_bdn) self.node.on_block_seen_by_blockchain_node.assert_called_once() self.node.block_queuing_service_manager.push.assert_not_called() self.node.block_processing_service.queue_block_for_processing.assert_not_called()
def test_message_tracked_correctly_when_framed(self): block_stats.add_block_event_by_block_hash = MagicMock() # send the handshake message self.node.on_bytes_sent(self.connection_fileno, 307) self.node.on_bytes_written_to_socket(self.connection_fileno, 307) block_message = NewBlockEthProtocolMessage( None, mock_eth_messages.get_dummy_block( 1, mock_eth_messages.get_dummy_block_header(5, int(time.time()))), 10) block_message.serialize() self.connection.enqueue_msg(block_message) message_length = self.connection.outputbuf.length for message in self.connection.message_tracker.messages: print(message.length) block_stats.add_block_event_by_block_hash.assert_not_called() self.assertEqual(message_length, self.connection.message_tracker.messages[0].length) self.node.on_bytes_sent(self.connection_fileno, message_length) self.node.on_bytes_written_to_socket(self.connection_fileno, message_length) block_stats.add_block_event_by_block_hash.assert_called_once()
def test_block_bodies_msg__get_block_transactions(self): txs = [] txs_bytes = [] txs_hashes = [] tx_count = 10 for i in range(1, tx_count): tx = mock_eth_messages.get_dummy_transaction(1) txs.append(tx) tx_bytes = rlp.encode(LegacyTransaction.serialize(tx)) txs_bytes.append(tx_bytes) tx_hash = tx.hash() txs_hashes.append(tx_hash) al_tx = mock_eth_messages.get_dummy_access_list_transaction(11) txs.append(al_tx) txs_bytes.append(Transaction.serialize(al_tx)) txs_hashes.append(al_tx.hash()) uncles = [ mock_eth_messages.get_dummy_block_header(2), mock_eth_messages.get_dummy_block_header(3), ] block_body = TransientBlockBody(txs, uncles) block_body_bytes = rlp.encode(block_body) block_bodies_msg = BlockBodiesEthProtocolMessage.from_body_bytes( block_body_bytes) parsed_txs_bytes = block_bodies_msg.get_block_transaction_bytes(0) self.assertEqual(len(parsed_txs_bytes), len(txs_hashes)) for index, parsed_tx_bytes in enumerate(parsed_txs_bytes): self.assertEqual( convert.bytes_to_hex(txs_bytes[index]), convert.bytes_to_hex(parsed_tx_bytes), f"failed at index {index}", ) parsed_txs_hashes = block_bodies_msg.get_block_transaction_hashes(0) self.assertEqual(len(parsed_txs_hashes), len(txs_hashes)) for index, parsed_tx_hash in enumerate(parsed_txs_hashes): self.assertEqual(parsed_tx_hash, txs_hashes[index])
def generate_new_eth_block(self) -> NewBlockEthProtocolMessage: block_message = NewBlockEthProtocolMessage( None, mock_eth_messages.get_dummy_block(1, mock_eth_messages.get_dummy_block_header(5, int(time.time()))), 10 ) block_message.serialize() return block_message
def generate_new_eth_block(self, block_number=10) -> InternalEthBlockInfo: block_message = NewBlockEthProtocolMessage( None, mock_eth_messages.get_dummy_block( 1, mock_eth_messages.get_dummy_block_header( 5, int(time.time()), block_number=block_number)), 10) block_message.serialize() internal_block_message = InternalEthBlockInfo.from_new_block_msg( block_message) return internal_block_message
def test_new_block_parts(self): txs = [] txs_bytes = [] txs_hashes = [] tx_count = 10 for i in range(1, tx_count): tx = mock_eth_messages.get_dummy_transaction(1) txs.append(tx) tx_bytes = rlp.encode(tx, Transaction) txs_bytes.append(tx_bytes) tx_hash = tx.hash() txs_hashes.append(tx_hash) block_header = mock_eth_messages.get_dummy_block_header(1) uncles = [ mock_eth_messages.get_dummy_block_header(2), mock_eth_messages.get_dummy_block_header(3), ] block_number = 100000 block_body = TransientBlockBody(txs, uncles) block_header_bytes = memoryview( rlp.encode(BlockHeader.serialize(block_header))) block_body_bytes = memoryview( rlp.encode(TransientBlockBody.serialize(block_body))) new_block_parts = NewBlockParts(block_header_bytes, block_body_bytes, block_number) self.assertIsInstance(new_block_parts.get_block_hash(), Sha256Hash) self.assertIsInstance(new_block_parts.get_previous_block_hash(), Sha256Hash) self.assertEqual(1, new_block_parts.get_block_difficulty())
def test_block_headers_msg_from_header_bytes(self): block_header = mock_eth_messages.get_dummy_block_header(1) block_header_bytes = memoryview( rlp.encode(BlockHeader.serialize(block_header))) block_headers_msg = BlockHeadersEthProtocolMessage.from_header_bytes( block_header_bytes) raw_headers = block_headers_msg.get_block_headers() headers_list = list(raw_headers) self.assertEqual(len(headers_list), 1) self.assertTrue(headers_list) self.assertEqual(1, len(block_headers_msg.get_block_headers())) self.assertEqual(1, len(block_headers_msg.get_block_headers_bytes())) self.assertEqual(block_header, block_headers_msg.get_block_headers()[0]) self.assertEqual( block_header_bytes.tobytes(), block_headers_msg.get_block_headers_bytes()[0].tobytes())
def test_complete_header_body_fetch(self): self.node.block_processing_service.queue_block_for_processing = MagicMock() self.sut.is_valid_block_timestamp = MagicMock(return_value=True) header = mock_eth_messages.get_dummy_block_header(1) block = mock_eth_messages.get_dummy_block(1, header) block_hash = header.hash_object() new_block_hashes_message = NewBlockHashesEthProtocolMessage.from_block_hash_number_pair( block_hash, 1 ) header_message = BlockHeadersEthProtocolMessage(None, [header]) bodies_message = BlockBodiesEthProtocolMessage(None, [TransientBlockBody(block.transactions, block.uncles)]) self.sut.msg_new_block_hashes(new_block_hashes_message) self.assertEqual(1, len(self.sut.pending_new_block_parts.contents)) self.assertEqual(2, len(self.enqueued_messages)) self.sut.msg_block_headers(header_message) self.sut.msg_block_bodies(bodies_message) self.node.block_processing_service.queue_block_for_processing.assert_called_once()
def _block_with_timestamp(timestamp): nonce = 5 header = mock_eth_messages.get_dummy_block_header(5, int(timestamp)) block = mock_eth_messages.get_dummy_block(nonce, header) return block
def test_bx_block_to_block__full_txs_success(self): tx_count = 150 txs = [] short_txs = [] short_ids = [] for i in range(1, tx_count): tx = mock_eth_messages.get_dummy_transaction(1) txs.append(tx) tx_bytes = rlp.encode(tx, Transaction) if i % 2 == 0: tx_hash = hashlib.sha256(tx_bytes).digest() self.tx_service.assign_short_id(tx_hash, i) self.tx_service.set_transaction_contents(tx_hash, tx_bytes) short_tx = ShortTransaction(0, bytes()) short_txs.append(short_tx) short_ids.append(i) else: short_tx = ShortTransaction(1, tx_bytes) short_txs.append(short_tx) dummy_chain_difficulty = 20 dummy_block_number = 10 compact_block = CompactBlock(mock_eth_messages.get_dummy_block_header(8), short_txs, [ mock_eth_messages.get_dummy_block_header(2), mock_eth_messages.get_dummy_block_header(3) ], dummy_chain_difficulty, dummy_block_number) compact_block_msg_bytes = bytearray(constants.UL_ULL_SIZE_IN_BYTES) compact_block_msg_bytes.extend(rlp.encode(compact_block, CompactBlock)) short_ids_offset = len(compact_block_msg_bytes) struct.pack_into("<Q", compact_block_msg_bytes, 0, short_ids_offset) compact_block_bytes = compact_block_short_ids_serializer.serialize_short_ids_into_bytes(short_ids) compact_block_msg_bytes.extend(compact_block_bytes) compact_block_hash_bytes = hashlib.sha256(compact_block_msg_bytes).digest() compact_block_hash = Sha256Hash(compact_block_hash_bytes) bx_block_msg = BroadcastMessage(compact_block_hash, self.test_network_num, is_encrypted=True, blob=compact_block_msg_bytes) block_msg, block_info, unknown_tx_sids, unknown_tx_hashes = self.eth_message_converter.bx_block_to_block( bx_block_msg.blob(), self.tx_service) self.assertTrue(block_msg) self.assertIsInstance(block_msg, InternalEthBlockInfo) new_block_msg = block_msg.to_new_block_msg() block = new_block_msg.get_block() self._assert_values_equal(compact_block.header, block.header) self._assert_values_equal(compact_block.uncles, block.uncles) self.assertEqual(len(compact_block.transactions), len(block.transactions)) for block_tx, i in zip(block.transactions, range(0, tx_count - 1)): self.assertIsInstance(block_tx, Transaction) self._assert_values_equal(block_tx, txs[i]) self.assertEqual(compact_block.chain_difficulty, new_block_msg.chain_difficulty)
def test_block_to_bx_block__no_compressed_block(self): txs = [] txs_bytes = [] txs_hashes = [] short_ids = [] used_short_ids = [] tx_count = 150 for i in range(1, tx_count): tx = mock_eth_messages.get_dummy_transaction(1) txs.append(tx) tx_bytes = rlp.encode(tx, Transaction) txs_bytes.append(tx_bytes) tx_hash = tx.hash() txs_hashes.append(tx_hash) short_ids.append(0) block = Block( mock_eth_messages.get_dummy_block_header(1), txs, [ mock_eth_messages.get_dummy_block_header(2), mock_eth_messages.get_dummy_block_header(3), ] ) dummy_chain_difficulty = 10 block_msg = NewBlockEthProtocolMessage(None, block, dummy_chain_difficulty) self.assertTrue(block_msg.rawbytes()) internal_new_block_msg = InternalEthBlockInfo.from_new_block_msg(block_msg) bx_block_msg, block_info = self.eth_message_converter.block_to_bx_block( internal_new_block_msg, self.tx_service, False, 0 ) self.assertTrue(len(bx_block_msg) >= len(internal_new_block_msg.rawbytes())) self.assertEqual(len(txs), block_info.txn_count) self.assertEqual(convert.bytes_to_hex(block.header.prev_hash), block_info.prev_block_hash) self.assertEqual(used_short_ids, list(block_info.short_ids)) self.assertTrue(bx_block_msg) self.assertIsInstance(bx_block_msg, memoryview) block_offsets = compact_block_short_ids_serializer.get_bx_block_offsets(bx_block_msg) compact_block = rlp.decode( bx_block_msg[block_offsets.block_begin_offset: block_offsets.short_id_offset].tobytes(), CompactBlock ) self.assertTrue(compact_block) self.assertIsInstance(compact_block, CompactBlock) self._assert_values_equal(compact_block.header, block.header) self._assert_values_equal(compact_block.uncles, block.uncles) self.assertEqual(len(compact_block.transactions), len(block.transactions)) for tx, short_tx, i in zip(block.transactions, compact_block.transactions, range(1, tx_count)): self.assertIsInstance(tx, Transaction) self.assertIsInstance(short_tx, ShortTransaction) self.assertEqual(1, short_tx.full_transaction) self.assertEqual(short_tx.transaction_bytes, txs_bytes[i - 1]) self.assertEqual(compact_block.chain_difficulty, block_msg.chain_difficulty) converted_block_msg, _, _, _ = self.eth_message_converter.bx_block_to_block(bx_block_msg, self.tx_service) self.assertIsNotNone(converted_block_msg)