def validate_block(self, block: BlockAPI) -> None: if not isinstance(block, self.get_block_class()): raise ValidationError( f"This vm ({self!r}) is not equipped to validate a block of type {block!r}" ) if block.is_genesis: validate_length_lte(block.header.extra_data, self.extra_data_max_bytes, title="BlockHeader.extra_data") else: parent_header = get_parent_header(block.header, self.chaindb) self.validate_header(block.header, parent_header) tx_root_hash, _ = make_trie_root_and_nodes(block.transactions) if tx_root_hash != block.header.transaction_root: raise ValidationError( f"Block's transaction_root ({block.header.transaction_root}) " f"does not match expected value: {tx_root_hash}") if len(block.uncles) > MAX_UNCLES: raise ValidationError( f"Blocks may have a maximum of {MAX_UNCLES} uncles. " f"Found {len(block.uncles)}.") if not self.chaindb.exists(block.header.state_root): raise ValidationError("`state_root` was not found in the db.\n" f"- state_root: {block.header.state_root}") local_uncle_hash = keccak(rlp.encode(block.uncles)) if local_uncle_hash != block.header.uncles_hash: raise ValidationError( "`uncles_hash` and block `uncles` do not match.\n" f" - num_uncles : {len(block.uncles)}\n" f" - block uncle_hash : {local_uncle_hash}\n" f" - header uncle_hash: {block.header.uncles_hash}")
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_block(self, block: BaseBlock) -> None: """ Validate the the given block. """ if not isinstance(block, self.get_block_class()): raise ValidationError( "This vm ({0!r}) is not equipped to validate a block of type {1!r}".format( self, block, ) ) if block.is_genesis: validate_length_lte(block.header.extra_data, 32, title="BlockHeader.extra_data") else: parent_header = get_parent_header(block.header, self.chaindb) self.validate_header(block.header, parent_header) tx_root_hash, _ = make_trie_root_and_nodes(block.transactions) if tx_root_hash != block.header.transaction_root: raise ValidationError( "Block's transaction_root ({0}) does not match expected value: {1}".format( block.header.transaction_root, tx_root_hash)) if len(block.uncles) > MAX_UNCLES: raise ValidationError( "Blocks may have a maximum of {0} uncles. Found " "{1}.".format(MAX_UNCLES, len(block.uncles)) ) if not self.chaindb.exists(block.header.state_root): raise ValidationError( "`state_root` was not found in the db.\n" "- state_root: {0}".format( block.header.state_root, ) ) local_uncle_hash = keccak(rlp.encode(block.uncles)) if local_uncle_hash != block.header.uncles_hash: raise ValidationError( "`uncles_hash` and block `uncles` do not match.\n" " - num_uncles : {0}\n" " - block uncle_hash : {1}\n" " - header uncle_hash: {2}".format( len(block.uncles), local_uncle_hash, block.header.uncles_hash, ) )
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_max_packet_size(encoded_packet: bytes) -> None: validate_length_lte(encoded_packet, MAX_PACKET_SIZE, "packet")
def test_validate_length_lte(value, maximum_length, is_valid): if is_valid: validate_length_lte(value, maximum_length) else: with pytest.raises(ValidationError): validate_length_lte(value, maximum_length)