Validates a child EEVM.Block.Header against its parent.
Covers the consensus rules that don't require running the EVM:
parent_hashmatches the parent header'shash.numberis one greater than the parent's number.timestampis strictly greater than the parent's timestamp.extra_datais at most 32 bytes.gas_limitis at least 5,000, fits in a signed 64-bit integer, and differs from the parent's gas limit by less thanparent_gas_limit / 1024.- Each fork-dependent field is present exactly when its fork is active:
base_fee_per_gas(London),withdrawals_root(Shanghai),blob_gas_used,excess_blob_gas, andparent_beacon_block_root(Cancun),requests_hash(Prague). - From London,
base_fee_per_gasequals the value derived from the parent's base fee, gas used, and gas target (EIP-1559). - From Paris,
difficultyis 0,nonceis eight zero bytes, andommers_hashisEEVM.Block.Header.empty_ommers_hash/0(EIP-3675). - From Cancun,
blob_gas_usedis a multiple of the per-blob gas and at mostEEVM.Gas.Blob.max_blob_gas_per_block/1.excess_blob_gasequalsEEVM.Gas.Blob.calc_excess_blob_gas/2of the parent (EIP-4844, EIP-7691 from Prague, EIP-7918 from Osaka).
Checks run in that order and the first failure wins. The parent is judged under the same fork as the child, so a fork's first block (such as London's, whose expected base fee is the initial 1 gwei) isn't modelled.
Checks against the block body and the execution result (transactions_root,
withdrawals_root, gas_used, receipts_root, state_root, ...) live in
EEVM.Block.validate/3 and EEVM.Block.execute/4.
Summary
Types
Reason returned when a header fails validation; see EEVM.Error.
Functions
Returns :ok when child is a valid successor of parent, otherwise
{:error, reason} for the first rule it breaks. hardfork selects the
fork-dependent rules and defaults to EEVM.HardforkConfig.default/0.
Types
@type error() :: EEVM.Error.header_validation_error()
Reason returned when a header fails validation; see EEVM.Error.
Functions
@spec validate(EEVM.Block.Header.t(), EEVM.Block.Header.t(), EEVM.HardforkConfig.t()) :: :ok | {:error, error()}
Returns :ok when child is a valid successor of parent, otherwise
{:error, reason} for the first rule it breaks. hardfork selects the
fork-dependent rules and defaults to EEVM.HardforkConfig.default/0.
Example
iex> alias EEVM.Block.{Header, HeaderValidator}
iex> shanghai = EEVM.HardforkConfig.new(:shanghai)
iex> parent = Header.new(number: 1, timestamp: 10, gas_limit: 30_000_000, hash: <<1::256>>)
iex> fields = [base_fee_per_gas: 0, withdrawals_root: <<0::256>>]
iex> parent = struct!(parent, fields)
iex> child = Header.new([number: 2, timestamp: 22, gas_limit: 30_000_000, parent_hash: <<1::256>>] ++ fields)
iex> HeaderValidator.validate(child, parent, shanghai)
:ok
iex> HeaderValidator.validate(%{child | timestamp: 10}, parent, shanghai)
{:error, :invalid_timestamp}