예제 #1
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])
예제 #2
0
    async def test_subscription(self):
        tx_hash = helpers.generate_object_hash()
        tx_contents = mock_eth_messages.get_dummy_transaction(1)
        transaction_key = self.gateway_node.get_tx_service(
        ).get_transaction_key(tx_hash)
        self.gateway_node.get_tx_service().set_transaction_contents_by_key(
            transaction_key, rlp.encode(tx_contents))

        tx_hash_2 = helpers.generate_object_hash()
        tx_contents_2 = mock_eth_messages.get_dummy_transaction(2)
        transaction_key_2 = self.gateway_node.get_tx_service(
        ).get_transaction_key(tx_hash_2)
        self.gateway_node.get_tx_service().set_transaction_contents_by_key(
            transaction_key_2, rlp.encode(tx_contents_2))

        await self.eth_ws_server_message_queue.put(
            (TX_SUB_ID, f"0x{convert.bytes_to_hex(tx_hash.binary)}"))
        await self.eth_ws_server_message_queue.put(
            (TX_SUB_ID, f"0x{convert.bytes_to_hex(tx_hash_2.binary)}"))
        await asyncio.sleep(0.01)

        self.assertEqual(2, self.subscriber.messages.qsize())

        tx_message_1 = await self.subscriber.receive()
        self.assertEqual(f"0x{convert.bytes_to_hex(tx_hash.binary)}",
                         tx_message_1["tx_hash"])
        self.assertEqual(tx_contents.to_json(), tx_message_1["tx_contents"])

        tx_message_2 = await self.subscriber.receive()
        self.assertEqual(f"0x{convert.bytes_to_hex(tx_hash_2.binary)}",
                         tx_message_2["tx_hash"])
        self.assertEqual(tx_contents_2.to_json(), tx_message_2["tx_contents"])
예제 #3
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)
예제 #4
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)
예제 #5
0
    def test_berlin_block_from_bytes(self):
        block: Block = rlp.decode(eth_fixtures.BERLIN_BLOCK, Block)

        self.assertEqual(
            Sha256Hash.from_string(
                "0ad3836807aa90218884be62c8dd912fe5228aafa6fc2a7c21028e8c09bc91ef"
            ),
            block.header.hash_object(),
        )
        self.assertEqual(2, len(block.transactions))

        legacy_tx = block.transactions[0]
        self.assertIsInstance(legacy_tx, LegacyTransaction)
        self.assertEqual(
            Sha256Hash.from_string(
                "77b19baa4de67e45a7b26e4a220bccdbb6731885aa9927064e239ca232023215"
            ),
            legacy_tx.hash(),
        )

        acl_tx = block.transactions[1]
        self.assertIsInstance(acl_tx, AccessListTransaction)
        self.assertEqual(
            Sha256Hash.from_string(
                "554af720acf477830f996f1bc5d11e54c38aa40042aeac6f66cb66f9084a959d"
            ),
            acl_tx.hash(),
        )

        re_encoded = rlp.encode(block)
        self.assertEqual(block, rlp.decode(re_encoded, Block))
예제 #6
0
    async def test_disconnect_server_revive(self):
        tx_hash = helpers.generate_object_hash()
        tx_contents = mock_eth_messages.get_dummy_transaction(1)
        transaction_key = self.gateway_node.get_tx_service(
        ).get_transaction_key(tx_hash)
        self.gateway_node.get_tx_service().set_transaction_contents_by_key(
            transaction_key, rlp.encode(tx_contents))

        self.eth_test_ws_server.close()
        await self.eth_test_ws_server.wait_closed()
        await self.eth_ws_server_message_queue.put(
            (TX_SUB_ID, f"0x{convert.bytes_to_hex(tx_hash.binary)}"))
        await self.eth_ws_proxy_publisher.close()

        await asyncio.sleep(0.05)

        self.assertEqual(0, self.subscriber.messages.qsize())
        self.assertFalse(self.eth_ws_proxy_publisher.running)

        await self.start_server()
        await asyncio.sleep(0)

        await self.eth_ws_proxy_publisher.revive()
        await self.eth_ws_server_message_queue.put(
            (TX_SUB_ID, f"0x{convert.bytes_to_hex(tx_hash.binary)}"))
        await asyncio.sleep(0.01)
        self.assertEqual(1, self.subscriber.messages.qsize())
예제 #7
0
 def get_unsigned(self) -> bytes:
     if self.is_eip_155_signed():
         parts = rlp.decode(rlp.encode(self))
         parts_for_signing = parts[:-3] + [eth_common_utils.int_to_big_endian(self.chain_id()), b'', b'']
         return rlp.encode(parts_for_signing)
     else:
         return rlp.encode(
             UnsignedTransaction(
                 self.nonce,
                 self.gas_price,
                 self.start_gas,
                 self.to,
                 self.value,
                 self.data
             )
         )
예제 #8
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])
예제 #9
0
 def test_legacy_transaction_eip_2718_from_bytes(self):
     transaction = Transaction.deserialize(
         eth_fixtures.LEGACY_TRANSACTION_EIP_2718)
     re_encoded = rlp.encode(transaction)
     self.assertEqual(
         Transaction.deserialize(eth_fixtures.LEGACY_TRANSACTION),
         transaction)
     self.assertEqual(transaction, rlp.decode(re_encoded, Transaction))
예제 #10
0
 def serialize(cls, obj, type_parsed: bool = False, **kwargs):
     if type_parsed:
         result = super().serialize(obj)
         if obj.transaction_type == EthTransactionType.LEGACY:
             return result
         return obj.transaction_type.encode_rlp() + rlp.encode(result)
     else:
         return obj.__class__.serialize(obj, type_parsed=True, **kwargs)
예제 #11
0
    def get_unsigned(self) -> bytes:
        """
        Returns unsigned transaction. EIP-2930 transaction are always EIP-155
        protected. They do not require any of the v/r/s values included.
        :return:
        """

        parts = rlp.decode(Transaction.serialize(self)[1:])
        return EthTransactionType.ACCESS_LIST.encode_rlp() + rlp.encode(
            parts[:-3])
예제 #12
0
파일: frame.py 프로젝트: CSeanXu/bxgateway
    def get_encoded_msg_type(self):
        """
        Returns RLP-encoded message type
        :return: bytes of RLP-encoded message type
        """

        if self._sequence_id and self._sequence_id > 0:
            return b""

        return rlp.encode(self._msg_type,
                          sedes=rlp.sedes.big_endian_int)  # unsigned byte
예제 #13
0
    def get_unsigned(self) -> bytes:
        """
        Returns unsigned transaction.

        EIP-155 protected transactions require the chain ID encoded in the v
        field, and the r/s fields to be empty.
        :return:
        """
        if self.is_eip_155_signed():
            parts = rlp.decode(rlp.encode(Transaction.serialize(self)))
            parts_for_signing = parts[:-3] + [
                eth_common_utils.int_to_big_endian(self.chain_id()),
                b"",
                b"",
            ]
            return rlp.encode(parts_for_signing)
        else:
            return rlp.encode(
                UnsignedTransaction(self.nonce, self.gas_price, self.start_gas,
                                    self.to, self.value, self.data))
예제 #14
0
    def _serialize_rlp_payload(self):
        field_values = [getattr(self, field) for field, _ in self.fields]

        # get single value if message has just one field
        if len(field_values) == 1:
            field_values = field_values[0]

        payload = self._get_serializer().serialize(field_values)
        encoded_payload = rlp.encode(payload)

        return encoded_payload
예제 #15
0
def normalize_typed_transaction(tx_bytes: memoryview) -> memoryview:
    """
    RLP could be either [transaction_type][encoded transaction], or
    RLP([transaction_type][encoded transaction]). The first form cannot be
    `rlp.decode`d, as it will only return the transaction type or throw an
    exception if strict=True. Force it to be of the second type.
    """
    item_type, item_length, _item_start = rlp_utils.consume_length_prefix(tx_bytes, 0)
    if item_type == str and item_length == 1:
        tx_bytes = memoryview(rlp.encode(tx_bytes.tobytes()))

    return tx_bytes
예제 #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_msg_confirmed_tx(self):
        self.node.feed_manager.publish_to_feed = MagicMock()

        tx_hash = helpers.generate_object_hash()
        message = ConfirmedTxMessage(tx_hash)
        self.connection.msg_confirmed_tx(message)
        self.node.feed_manager.publish_to_feed.assert_not_called()

        tx_hash = helpers.generate_object_hash()
        message = ConfirmedTxMessage(
            tx_hash, rlp.encode(mock_eth_messages.get_dummy_transaction(1)))
        self.connection.msg_confirmed_tx(message)
        self.node.feed_manager.publish_to_feed.assert_called_once()
예제 #18
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)
예제 #19
0
 def _create_block_header_bytes(self, block_number: int,
                                difficulty: int) -> memoryview:
     block_header = BlockHeader(
         helpers.generate_bytes(eth_common_constants.BLOCK_HASH_LEN),
         helpers.generate_bytes(eth_common_constants.BLOCK_HASH_LEN),
         helpers.generate_bytes(eth_common_constants.ADDRESS_LEN),
         helpers.generate_bytes(eth_common_constants.MERKLE_ROOT_LEN),
         helpers.generate_bytes(eth_common_constants.MERKLE_ROOT_LEN),
         helpers.generate_bytes(eth_common_constants.MERKLE_ROOT_LEN), 100,
         difficulty, block_number, 3, 4, 1601410624,
         helpers.generate_bytes(100),
         helpers.generate_bytes(eth_common_constants.BLOCK_HASH_LEN),
         helpers.generate_bytes(12345))
     block_header_bytes = rlp.encode(block_header, BlockHeader)
     return memoryview(block_header_bytes)
예제 #20
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()),
        )
예제 #21
0
    def test_legacy_transaction_from_bytes(self):
        transaction = rlp.decode(eth_fixtures.LEGACY_TRANSACTION, Transaction)
        re_encoded = rlp.encode(transaction)

        self.assertEqual(transaction, rlp.decode(re_encoded, Transaction))

        self.assertEqual(EthTransactionType.LEGACY,
                         transaction.transaction_type)
        self.assertIsInstance(transaction, LegacyTransaction)
        self.assertEqual(
            Sha256Hash.from_string(eth_fixtures.LEGACY_TRANSACTION_HASH),
            transaction.hash(),
        )
        self.assertEqual("0xc296825bf94ca41b881390955c2731c1d3eaa059",
                         transaction.from_address())
        self.assertEqual(37, transaction.v)
예제 #22
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())
예제 #23
0
    def test_access_list_transaction_from_bytes(self):
        transaction: Transaction = rlp.decode(eth_fixtures.ACL_TRANSACTION,
                                              Transaction)
        re_encoded = rlp.encode(transaction)
        self.assertEqual(transaction, rlp.decode(re_encoded, Transaction))

        self.assertEqual(EthTransactionType.ACCESS_LIST,
                         transaction.transaction_type)
        self.assertIsInstance(transaction, AccessListTransaction)
        self.assertEqual(
            Sha256Hash.from_string(eth_fixtures.ACL_TRANSACTION_HASH),
            transaction.hash(),
        )
        self.assertEqual(1, transaction.chain_id())
        self.assertEqual(0, transaction.v)
        self.assertEqual("0x0087c5900b9bbc051b5f6299f5bce92383273b28",
                         transaction.from_address())
        self.assertEqual(3, len(transaction.access_list))
예제 #24
0
    def test_bx_tx_to_tx__success(self):
        tx = mock_eth_messages.get_dummy_transaction(1)

        tx_bytes = rlp.encode(tx, Transaction)
        tx_hash_bytes = hashlib.sha256(tx_bytes).digest()
        tx_hash = Sha256Hash(tx_hash_bytes)

        bx_tx_message = TxMessage(message_hash=tx_hash, network_num=self.test_network_num, tx_val=tx_bytes)

        tx_message = self.eth_message_converter.bx_tx_to_tx(bx_tx_message)

        self.assertIsNotNone(tx_message)
        self.assertIsInstance(tx_message, TransactionsEthProtocolMessage)

        self.assertTrue(tx_message.get_transactions())
        self.assertEqual(1, len(tx_message.get_transactions()))

        tx_obj = tx_message.get_transactions()[0]
        self.assertEqual(tx, tx_obj)
예제 #25
0
파일: frame.py 프로젝트: CSeanXu/bxgateway
    def get_header(self):
        """
        Returns frame header

        header: frame-size || header-data || padding
        frame-size: 3-byte integer size of frame, big endian encoded
        header-data:
            normal: rlp.list(protocol-type[, sequence-id])
            chunked-0: rlp.list(protocol-type, sequence-id, total-packet-size)
            chunked-n: rlp.list(protocol-type, sequence-id)
            normal, chunked-n: rlp.list(protocol-type[, sequence-id])
            values:
                protocol-type: < 2**16
                sequence-id: < 2**16 (this value is optional for normal frames)
                total-packet-size: < 2**32
        padding: zero-fill to 16-byte boundary
        :return: frame header bytes
        """

        header_parts = [self._protocol_id]

        if self._is_chunked and self._sequence_id == 0:
            header_parts.append(self._sequence_id)
            header_parts.append(self._total_payload_size)
        elif self._sequence_id is not None:  # normal, chunked_n
            header_parts.append(self._sequence_id)

        header_data = rlp.encode(header_parts,
                                 sedes=self.header_data_serializer)

        # write body_size to header
        # frame-size: 3-byte integer size of frame, big endian encoded (excludes padding)
        # frame relates to body w/o padding w/o mac
        body_size = self.get_body_size()
        assert body_size < eth_common_constants.FRAME_MAX_BODY_SIZE
        header = struct.pack(">I", body_size)[1:] + header_data
        header = crypto_utils.right_0_pad_16(header)  # padding
        assert len(header) == eth_common_constants.FRAME_HDR_DATA_LEN
        return header
예제 #26
0
 def contents(self) -> memoryview:
     return memoryview(rlp.encode(self))
예제 #27
0
 def hash_object(self) -> Sha256Hash:
     return Sha256Hash(eth_common_utils.keccak_hash(rlp.encode(self)))
예제 #28
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)
예제 #29
0
 def hash(self):
     hash_bytes = eth_common_utils.keccak_hash(rlp.encode(self))
     return Sha256Hash(hash_bytes)
예제 #30
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)