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)
示例#2
0
    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])
示例#3
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),
         ],
     )
示例#4
0
    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)
示例#5
0
    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)
示例#6
0
    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)
示例#7
0
    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()),
        )
示例#8
0
    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))
示例#9
0
    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()
        )
示例#10
0
    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)
示例#11
0
    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()
示例#12
0
    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()
示例#13
0
    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])
示例#14
0
 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
示例#15
0
 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
示例#16
0
    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())
示例#17
0
    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())
示例#18
0
    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
示例#20
0
    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)
示例#21
0
    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)