예제 #1
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()
예제 #2
0
    def test_bdn_stats_block_new_from_node_ignore_duplicate(self):
        block_msg = NewBlockEthProtocolMessage(
            None,
            _block_with_timestamp(
                time.time() + 1 -
                self.node.opts.blockchain_ignore_block_interval_count *
                self.node.opts.blockchain_block_interval), 10)
        block_msg.serialize()
        self.block_blockchain_connection_protocol.msg_block(block_msg)
        self.block_blockchain_connection_protocol.msg_block(block_msg)

        self.assertEqual(
            3,
            len(gateway_bdn_performance_stats_service.interval_data.
                blockchain_node_to_bdn_stats))
        node_1_stats = gateway_bdn_performance_stats_service.interval_data.blockchain_node_to_bdn_stats[
            self.node_1_endpoint]
        for endpoint, stats in gateway_bdn_performance_stats_service.interval_data.blockchain_node_to_bdn_stats.items(
        ):
            if endpoint == self.node_1_endpoint:
                continue
            self.assertEqual(1, stats.new_blocks_received_from_bdn)

        self.assertEqual(1,
                         node_1_stats.new_blocks_received_from_blockchain_node)
예제 #3
0
    def test_bdn_stats_block_new_from_bdn_ignore_from_node(self):
        block_msg = NewBlockEthProtocolMessage(
            None,
            _block_with_timestamp(time.time() + 1 - (
                self.node.opts.blockchain_ignore_block_interval_count *
                self.node.opts.blockchain_block_interval)), 10)

        internal_new_block_msg = InternalEthBlockInfo.from_new_block_msg(
            block_msg)
        msg_bytes, block_info = self.node.message_converter.block_to_bx_block(
            internal_new_block_msg, self.node._tx_service, True,
            self.node.network.min_tx_age_seconds)
        msg_hash = Sha256Hash(crypto.double_sha256(msg_bytes))
        broadcast_msg = BroadcastMessage(message_hash=msg_hash,
                                         network_num=1,
                                         is_encrypted=False,
                                         blob=msg_bytes)
        self.relay_connection.msg_broadcast(broadcast_msg)

        block_msg.serialize()
        self.block_blockchain_connection_protocol.msg_block(block_msg)

        self.assertEqual(
            3,
            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_bdn)
            self.assertEqual(0, stats.new_blocks_received_from_blockchain_node)
예제 #4
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)
예제 #5
0
    def msg_block(self, msg: NewBlockEthProtocolMessage):
        if not self.node.should_process_block_hash(msg.block_hash()):
            return

        self.node.set_known_total_difficulty(msg.block_hash(), msg.chain_difficulty())

        internal_new_block_msg = InternalEthBlockInfo.from_new_block_msg(msg)
        super().msg_block(internal_new_block_msg)
예제 #6
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
예제 #7
0
    def from_new_block_msg(
            cls, new_block_msg: NewBlockEthProtocolMessage
    ) -> "InternalEthBlockInfo":
        """
        Creates NewBlockInternalEthMessage from raw bytes of NewBlockEthProtocolMessage
        :param new_block_msg: new block message
        :return: NewBlockInternalEthMessage message
        """
        new_block_msg_bytes = memoryview(new_block_msg.rawbytes())

        _, block_msg_itm_len, block_msg_itm_start = rlp_utils.consume_length_prefix(
            new_block_msg_bytes, 0)
        block_msg_bytes = new_block_msg_bytes[
            block_msg_itm_start:block_msg_itm_start + block_msg_itm_len]

        msg_size = 0

        # block item already include header, transactions and uncles
        _, block_itm_len, block_itm_start = rlp_utils.consume_length_prefix(
            block_msg_bytes, 0)
        block_itm_bytes = block_msg_bytes[
            block_msg_itm_start:block_msg_itm_start + block_itm_len]
        msg_size += len(block_itm_bytes)

        difficulty_bytes = block_msg_bytes[block_msg_itm_start +
                                           block_itm_len:]
        msg_size += len(difficulty_bytes)

        block_number_bytes = rlp_utils.encode_int(new_block_msg.number())
        msg_size += len(block_number_bytes)

        msg_prefix = rlp_utils.get_length_prefix_list(
            len(block_itm_bytes) + len(difficulty_bytes) +
            len(block_number_bytes))
        msg_size += len(msg_prefix)

        msg_bytes = bytearray(msg_size)

        written_bytes = 0

        msg_bytes[written_bytes:written_bytes + len(msg_prefix)] = msg_prefix
        written_bytes += len(msg_prefix)

        msg_bytes[written_bytes:written_bytes +
                  len(block_itm_bytes)] = block_itm_bytes
        written_bytes += len(block_itm_bytes)

        msg_bytes[written_bytes:written_bytes +
                  len(difficulty_bytes)] = difficulty_bytes
        written_bytes += len(difficulty_bytes)

        msg_bytes[written_bytes:written_bytes +
                  len(block_number_bytes)] = block_number_bytes
        written_bytes += len(block_number_bytes)

        assert written_bytes == msg_size

        return cls(msg_bytes)
예제 #8
0
 def test_msg_block_in_recovery(self):
     message = NewBlockEthProtocolMessage(
         None, _block_with_timestamp(time.time()), 10)
     self.node.block_recovery_service.add_block(message.rawbytes(),
                                                message.block_hash(), [1],
                                                [])
     self.sut.msg_block(message)
     self.node.block_processing_service.queue_block_for_processing.assert_not_called(
     )
예제 #9
0
 def clean_block_transactions(
         self, block_msg: NewBlockEthProtocolMessage,
         transaction_service: TransactionService) -> None:
     block_hash = block_msg.block_hash()
     transactions_list = block_msg.txns()
     self.clean_block_transactions_by_block_components(
         block_hash=block_hash,
         transactions_list=(tx.hash() for tx in transactions_list),
         transaction_service=transaction_service)
예제 #10
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
 def test_msg_block_too_old(self):
     message = NewBlockEthProtocolMessage(
         None,
         _block_with_timestamp(
             time.time() - 1 - self.node.opts.blockchain_ignore_block_interval_count * self.node.opts.blockchain_block_interval
         ),
         10
     )
     message.serialize()
     self.sut.msg_block(message)
     self.node.block_processing_service.queue_block_for_processing.assert_not_called()
    def msg_block(self, msg: NewBlockEthProtocolMessage) -> None:
        if not self.node.should_process_block_hash(msg.block_hash()):
            return

        self.node.set_known_total_difficulty(msg.block_hash(),
                                             msg.get_chain_difficulty())

        internal_new_block_msg = InternalEthBlockInfo.from_new_block_msg(msg)
        self.process_msg_block(internal_new_block_msg, msg.number())

        if self.node.opts.filter_txs_factor > 0:
            self.node.on_transactions_in_block(msg.txns())
예제 #13
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)
예제 #14
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()),
        )
 def _get_sample_block(self, file_path):
     root_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(file_path))))
     with open(os.path.join(root_dir, "samples/eth_sample_block.txt")) as sample_file:
         btc_block = sample_file.read().strip("\n")
     buf = bytearray(convert.hex_to_bytes(btc_block))
     parsed_block = NewBlockEthProtocolMessage(msg_bytes=buf)
     return parsed_block
예제 #16
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()
        )
예제 #17
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))
예제 #18
0
def new_block_eth_protocol_message(
    nonce: int,
    block_number: Optional[int] = None,
    prev_block_hash: Optional[Sha256Hash] = None
) -> NewBlockEthProtocolMessage:
    header = get_dummy_block_header(nonce,
                                    block_number=block_number,
                                    prev_block_hash=prev_block_hash)
    block = get_dummy_block(nonce, header)
    return NewBlockEthProtocolMessage(None, block, nonce * 5 + 10)
예제 #19
0
    async def test_eth_transaction_receipts_feed_specify_include(self):
        self.gateway_node.opts.eth_ws_uri = f"ws://{constants.LOCALHOST}:8005"
        self.gateway_node.feed_manager.register_feed(
            EthTransactionReceiptsFeed(self.gateway_node, 0))
        self.gateway_node.eth_ws_proxy_publisher = MockEthWsProxyPublisher(
            "", None, None, self.gateway_node)
        receipt_response = {
            "blockHash":
            "0xe6f67c6948158c45dct10b169ad6bf3a96c6402489733a03051feaf7d09e7b54",
            "blockNumber": "0xaf25e5",
            "cumulativeGasUsed": "0xbdb9ae",
            "from": "0x82170dd1cec50107963bf1ba1e80955ea302c5ce",
            "gasUsed": "0x5208",
            "logs": [],
            "logsBloom":
            "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
            "status": "0x1",
            "to": "0xa09f63d9a0b0fbe89e41e51282ad660e7c876165",
            "transactionHash":
            "0xbcdc5b22bf463f9b8766dd61cc133caf13472b6ae8474061134d9dc2983625f6",
            "transactionIndex": "0x90"
        }
        receipt_result = {
            "transactionHash":
            "0xbcdc5b22bf463f9b8766dd61cc133caf13472b6ae8474061134d9dc2983625f6"
        }
        self.gateway_node.eth_ws_proxy_publisher.call_rpc = AsyncMock(
            return_value=JsonRpcResponse(request_id=1,
                                         result=receipt_response))
        block = mock_eth_messages.get_dummy_block(5)
        internal_block_info = InternalEthBlockInfo.from_new_block_msg(
            NewBlockEthProtocolMessage(None, block, 1))
        eth_raw_block = EthRawBlock(
            1, internal_block_info.block_hash(), FeedSource.BLOCKCHAIN_RPC,
            get_block_message_lazy(internal_block_info))

        async with WsProvider(self.ws_uri) as ws:
            subscription_id = await ws.subscribe(
                rpc_constants.ETH_TRANSACTION_RECEIPTS_FEED_NAME,
                {"include": ["receipt.transaction_hash"]})

            self.gateway_node.feed_manager.publish_to_feed(
                FeedKey(rpc_constants.ETH_TRANSACTION_RECEIPTS_FEED_NAME),
                eth_raw_block)

            for i in range(len(block.transactions)):
                subscription_message = await ws.get_next_subscription_notification_by_id(
                    subscription_id)
                self.assertEqual(subscription_id,
                                 subscription_message.subscription_id)
                self.assertEqual(subscription_message.notification,
                                 {"receipt": receipt_result})
예제 #20
0
    def send_block_to_node(
        self,
        block_hash: Sha256Hash,
        block_msg: Optional[InternalEthBlockInfo] = None,
    ) -> None:
        assert block_msg is not None

        # block must always be greater than previous best
        block_number = block_msg.block_number()
        best_height, _best_hash, _ = self.best_sent_block
        assert block_number > best_height

        new_block_parts = self.node.block_parts_storage[block_hash]

        if block_msg.has_total_difficulty():
            new_block_msg = block_msg.to_new_block_msg()
            super(EthBlockQueuingService,
                  self).send_block_to_node(block_hash, new_block_msg)
            self.node.set_known_total_difficulty(
                new_block_msg.block_hash(),
                new_block_msg.get_chain_difficulty())
        else:
            calculated_total_difficulty = self.node.try_calculate_total_difficulty(
                block_hash, new_block_parts)

            if calculated_total_difficulty is None:
                # Total difficulty may be unknown after a long fork or
                # if gateways just started. Announcing new block hashes to
                # ETH node in that case. It
                # will request header and body separately.
                new_block_headers_msg = NewBlockHashesEthProtocolMessage.from_block_hash_number_pair(
                    block_hash, new_block_parts.block_number)
                super(EthBlockQueuingService,
                      self).send_block_to_node(block_hash,
                                               new_block_headers_msg)
            else:
                new_block_msg = NewBlockEthProtocolMessage.from_new_block_parts(
                    new_block_parts, calculated_total_difficulty)
                super(EthBlockQueuingService,
                      self).send_block_to_node(block_hash, new_block_msg)

        self.node.log_blocks_network_content(self.node.network_num, block_msg)
        self.sent_block_at_height[block_number] = block_hash
        self.best_sent_block = SentEthBlockInfo(block_number, block_hash,
                                                time.time())
        self._schedule_confirmation_check(block_hash)

        if self.node.opts.filter_txs_factor > 0:
            self.node.on_transactions_in_block(
                block_msg.to_new_block_msg().txns())
예제 #21
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)
예제 #22
0
    def test_header_body_fetch_abort_from_bdn(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)])
        internal_block_info = InternalEthBlockInfo.from_new_block_msg(NewBlockEthProtocolMessage(None, block, 1))

        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.node.on_block_received_from_bdn(block_hash, internal_block_info)

        self.sut.msg_block_headers(header_message)
        self.sut.msg_block_bodies(bodies_message)

        self.node.block_processing_service.queue_block_for_processing.assert_not_called()
예제 #23
0
    def to_new_block_msg(self) -> NewBlockEthProtocolMessage:
        """
        Converts message to instance of NewBlockEthProtocolMessage
        :return: instance of NewBlockEthProtocolMessage
        """

        _, msg_itm_len, msg_itm_start = rlp_utils.consume_length_prefix(
            self._memory_view, 0)
        msg_itm_bytes = self._memory_view[msg_itm_start:]

        offset = 0
        msg_size = 0

        _, header_len, header_start = rlp_utils.consume_length_prefix(
            msg_itm_bytes, offset)
        header_bytes = msg_itm_bytes[offset:header_start + header_len]
        offset = header_start + header_len
        msg_size += len(header_bytes)

        _, txs_len, txs_start = rlp_utils.consume_length_prefix(
            msg_itm_bytes, offset)
        txs_bytes = msg_itm_bytes[offset:txs_start + txs_len]
        offset = txs_start + txs_len
        msg_size += len(txs_bytes)

        _, uncles_len, uncles_start = rlp_utils.consume_length_prefix(
            msg_itm_bytes, offset)
        uncles_bytes = msg_itm_bytes[offset:uncles_start + uncles_len]
        offset = uncles_start + uncles_len
        msg_size += len(uncles_bytes)

        _, total_difficulty_len, total_difficulty_start = rlp_utils.consume_length_prefix(
            msg_itm_bytes, offset)
        total_difficulty_bytes = msg_itm_bytes[offset:total_difficulty_start +
                                               total_difficulty_len]
        msg_size += len(total_difficulty_bytes)

        block_prefix = rlp_utils.get_length_prefix_list(
            len(header_bytes) + len(txs_bytes) + len(uncles_bytes))
        msg_size += len(block_prefix)

        msg_prefix = rlp_utils.get_length_prefix_list(msg_size)
        msg_size += len(msg_prefix)

        result_msg_bytes = bytearray(msg_size)
        written_bytes = 0

        result_msg_bytes[written_bytes:written_bytes +
                         len(msg_prefix)] = msg_prefix
        written_bytes += len(msg_prefix)

        result_msg_bytes[written_bytes:written_bytes +
                         len(block_prefix)] = block_prefix
        written_bytes += len(block_prefix)

        result_msg_bytes[written_bytes:written_bytes +
                         len(header_bytes)] = header_bytes
        written_bytes += len(header_bytes)

        result_msg_bytes[written_bytes:written_bytes +
                         len(txs_bytes)] = txs_bytes
        written_bytes += len(txs_bytes)

        result_msg_bytes[written_bytes:written_bytes +
                         len(uncles_bytes)] = uncles_bytes
        written_bytes += len(uncles_bytes)

        result_msg_bytes[written_bytes:written_bytes +
                         len(total_difficulty_bytes)] = total_difficulty_bytes
        written_bytes += len(total_difficulty_bytes)

        assert written_bytes == msg_size

        return NewBlockEthProtocolMessage(result_msg_bytes)
예제 #24
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)