Example #1
0
    def try_calculate_total_difficulty(
            self, block_hash: Sha256Hash,
            new_block_parts: NewBlockParts) -> Optional[int]:
        previous_block_hash = new_block_parts.get_previous_block_hash()
        previous_block_total_difficulty = None

        for known_block_hash, known_total_difficulty in self._last_known_difficulties:
            if previous_block_hash == known_block_hash:
                previous_block_total_difficulty = known_total_difficulty
                break

        if previous_block_total_difficulty is None:
            logger.debug(
                "Unable to calculate total difficulty after block {}.",
                convert.bytes_to_hex(block_hash.binary))
            return None

        block_total_difficulty = previous_block_total_difficulty + new_block_parts.get_block_difficulty(
        )

        self._last_known_difficulties.append(
            (block_hash, block_total_difficulty))
        logger.debug("Calculated total difficulty after block {} = {}.",
                     convert.bytes_to_hex(block_hash.binary),
                     block_total_difficulty)

        return block_total_difficulty
Example #2
0
    def msg_new_block_hashes(self, msg: NewBlockHashesEthProtocolMessage):
        if not self.node.should_process_block_hash(msg.block_hash()):
            return

        block_hash_number_pairs = []
        for block_hash, block_number in msg.get_block_hash_number_pairs():
            block_stats.add_block_event_by_block_hash(
                block_hash,
                BlockStatEventType.BLOCK_ANNOUNCED_BY_BLOCKCHAIN_NODE,
                network_num=self.connection.network_num,
                more_info="Protocol: {}, Network: {}. {}".format(
                    self.node.opts.blockchain_protocol,
                    self.node.opts.blockchain_network, msg.extra_stats_data()),
                block_height=block_number,
            )
            gateway_bdn_performance_stats_service.log_block_message_from_blockchain_node(
                False)

            if block_hash in self.node.blocks_seen.contents:
                self.node.on_block_seen_by_blockchain_node(
                    block_hash, block_number=block_number)
                block_stats.add_block_event_by_block_hash(
                    block_hash,
                    BlockStatEventType.
                    BLOCK_RECEIVED_FROM_BLOCKCHAIN_NODE_IGNORE_SEEN,
                    network_num=self.connection.network_num,
                    block_height=block_number,
                )
                self.connection.log_info(
                    "Ignoring duplicate block {} from local blockchain node.",
                    block_hash)
                continue

            recovery_cancelled = self.node.on_block_seen_by_blockchain_node(
                block_hash, block_number=block_number)
            if recovery_cancelled:
                continue

            self.node.track_block_from_node_handling_started(block_hash)
            block_hash_number_pairs.append((block_hash, block_number))

            self.connection.log_info(
                "Fetching block {} from local Ethereum node.", block_hash)

        if not block_hash_number_pairs:
            return

        for block_hash, block_number in block_hash_number_pairs:
            # pyre-fixme[6]: Expected `memoryview` for 1st param but got `None`.
            self.pending_new_block_parts.add(
                block_hash, NewBlockParts(None, None, block_number))
            self.connection.enqueue_msg(
                GetBlockHeadersEthProtocolMessage(None, block_hash.binary, 1,
                                                  0, False))

        self.request_block_body(
            [block_hash for block_hash, _ in block_hash_number_pairs])
Example #3
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())
Example #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)
Example #5
0
    def to_new_block_parts(self) -> NewBlockParts:
        _, 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

        _, 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

        _, 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

        _, 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

        _, total_difficulty_len, total_difficulty_start = rlp_utils.consume_length_prefix(
            msg_itm_bytes, offset)
        offset = total_difficulty_start + total_difficulty_len

        block_number, _ = rlp_utils.decode_int(msg_itm_bytes, offset)

        block_body_prefix = rlp_utils.get_length_prefix_list(
            len(txs_bytes) + len(uncles_bytes))
        block_body_bytes = bytearray(
            len(block_body_prefix) + len(txs_bytes) + len(uncles_bytes))

        block_body_bytes[:len(block_body_prefix)] = block_body_prefix
        written_bytes = len(block_body_prefix)

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

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

        return NewBlockParts(header_bytes, block_body_bytes, block_number)