Ejemplo n.º 1
0
    def validate_header(cls, header: BlockHeaderAPI,
                        parent_header: BlockHeaderAPI) -> None:

        if parent_header is None:
            # to validate genesis header, check if it equals canonical header at block number 0
            raise ValidationError(
                "Must have access to parent header to validate current header")
        else:
            validate_length_lte(header.extra_data,
                                cls.extra_data_max_bytes,
                                title="BlockHeader.extra_data")

            validate_gas_limit(header.gas_limit, parent_header.gas_limit)

            if header.block_number != parent_header.block_number + 1:
                raise ValidationError(
                    "Blocks must be numbered consecutively. "
                    f"Block number #{header.block_number} "
                    f"has parent #{parent_header.block_number}")

            # timestamp
            if header.timestamp <= parent_header.timestamp:
                raise ValidationError(
                    "timestamp must be strictly later than parent, "
                    f"but is {parent_header.timestamp - header.timestamp} seconds before.\n"
                    f"- child  : {header.timestamp}\n"
                    f"- parent : {parent_header.timestamp}. ")
Ejemplo n.º 2
0
    def validate_header(
            cls, header: BlockHeader, parent_header: BlockHeader, check_seal: bool = True) -> None:
        """
        :raise eth.exceptions.ValidationError: if the header is not valid
        """
        if parent_header is None:
            # to validate genesis header, check if it equals canonical header at block number 0
            raise ValidationError("Must have access to parent header to validate current header")
        else:
            validate_length_lte(header.extra_data, 32, title="BlockHeader.extra_data")

            validate_gas_limit(header.gas_limit, parent_header.gas_limit)

            if header.block_number != parent_header.block_number + 1:
                raise ValidationError(
                    "Blocks must be numbered consecutively. Block number #{} has parent #{}".format(
                        header.block_number,
                        parent_header.block_number,
                    )
                )

            # timestamp
            if header.timestamp <= parent_header.timestamp:
                raise ValidationError(
                    "timestamp must be strictly later than parent, but is {} seconds before.\n"
                    "- child  : {}\n"
                    "- parent : {}. ".format(
                        parent_header.timestamp - header.timestamp,
                        header.timestamp,
                        parent_header.timestamp,
                    )
                )

            if check_seal:
                cls.validate_seal(header)
Ejemplo n.º 3
0
    def validate_uncle(cls, block: BlockAPI, uncle: BlockHeaderAPI,
                       uncle_parent: BlockHeaderAPI) -> None:

        if uncle.block_number >= block.number:
            raise ValidationError(
                f"Uncle number ({uncle.block_number}) is higher than "
                f"block number ({block.number})")
        if uncle.block_number != uncle_parent.block_number + 1:
            raise ValidationError(
                f"Uncle number ({uncle.block_number}) is not one above "
                f"ancestor's number ({uncle_parent.block_number})")
        if uncle.timestamp <= uncle_parent.timestamp:
            raise ValidationError(
                f"Uncle timestamp ({uncle.timestamp}) is not newer than its "
                f"parent's timestamp ({uncle_parent.timestamp})")
        if uncle.gas_used > uncle.gas_limit:
            raise ValidationError(
                f"Uncle's gas usage ({uncle.gas_used}) is above "
                f"the limit ({uncle.gas_limit})")

        uncle_parent_gas_limit = uncle_parent.gas_limit
        if not hasattr(uncle_parent, 'base_fee_per_gas') and hasattr(
                uncle, 'base_fee_per_gas'):
            # if Berlin -> London transition, double the parent limit for validation
            uncle_parent_gas_limit *= 2

        validate_gas_limit(uncle.gas_limit, uncle_parent_gas_limit)
Ejemplo n.º 4
0
    def validate_gas(cls, header: BlockHeaderAPI,
                     parent_header: BlockHeaderAPI) -> None:

        if hasattr(parent_header, 'base_fee_per_gas'):
            # Follow normal gas limit rules if the previous block had a base fee
            parent_gas_limit = parent_header.gas_limit
        else:
            # On the fork block, double the gas limit.
            # That way, the gas target (which is half the London limit) equals the
            # previous (pre-London) gas limit.
            parent_gas_limit = parent_header.gas_limit * ELASTICITY_MULTIPLIER

        validate_gas_limit(header.gas_limit, parent_gas_limit)

        expected_base_fee_per_gas = calculate_expected_base_fee_per_gas(
            parent_header)
        if expected_base_fee_per_gas != header.base_fee_per_gas:
            raise ValidationError(
                f"Header has invalid base fee per gas (has {header.base_fee_per_gas}"
                f", expected {expected_base_fee_per_gas})")
Ejemplo n.º 5
0
    def validate_header(cls,
                        header: BlockHeaderAPI,
                        parent_header: BlockHeaderAPI,
                        check_seal: bool = True) -> None:
        """
        :raise eth.exceptions.ValidationError: if the header is not valid
        """
        if parent_header is None:
            # to validate genesis header, check if it equals canonical header at block number 0
            raise ValidationError(
                "Must have access to parent header to validate current header")
        else:
            validate_length_lte(header.extra_data,
                                32,
                                title="BlockHeader.extra_data")

            validate_gas_limit(header.gas_limit, parent_header.gas_limit)

            if header.block_number != parent_header.block_number + 1:
                raise ValidationError(
                    "Blocks must be numbered consecutively. "
                    f"Block number #{header.block_number} "
                    f"has parent #{parent_header.block_number}")

            # timestamp
            if header.timestamp <= parent_header.timestamp:
                raise ValidationError(
                    "timestamp must be strictly later than parent, "
                    f"but is {parent_header.timestamp - header.timestamp} seconds before.\n"
                    f"- child  : {header.timestamp}\n"
                    f"- parent : {parent_header.timestamp}. ")

            if check_seal:
                try:
                    cls.validate_seal(header)
                except ValidationError:
                    cls.cls_logger.warning(
                        "Failed to validate header proof of work on header: %r",
                        header.as_dict())
                    raise
Ejemplo n.º 6
0
 def validate_gas(cls, header: BlockHeaderAPI,
                  parent_header: BlockHeaderAPI) -> None:
     validate_gas_limit(header.gas_limit, parent_header.gas_limit)