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}. ")
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)
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)
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})")
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
def validate_gas(cls, header: BlockHeaderAPI, parent_header: BlockHeaderAPI) -> None: validate_gas_limit(header.gas_limit, parent_header.gas_limit)