EEVM.HardforkConfig (eevm v0.1.0)

Copy Markdown View Source

Hardfork configuration controlling which EIP rules are active during execution.

Internal: callers use EEVM.Config.new/2, EEVM.Config.enabled?/2, and EEVM.Config.hardforks/0. eevm's own code gates rules with the enabled?/2 macro here, which rejects undeclared flags at compile time, and new flags go in @eip_activation.

The spec_id atom identifies the target hardfork, and enabled?/2 answers whether a given EIP is active under that spec.

Hardfork timeline (oldest → newest):

HardforkNotable EIPs
:frontierbaseline
:homesteadEIP-2 (contract-creation tx cost), EIP-7 (DELEGATECALL)
:tangerine_whistleEIP-150 gas repricing
:spurious_dragonEIP-155, EIP-160 (EXP cost), EIP-161, EIP-170 (code size limit)
:byzantiumEIP-140 (REVERT), EIP-196/197 (alt_bn128 precompiles), EIP-198 (ModExp precompile), EIP-211 (RETURNDATASIZE/RETURNDATACOPY), EIP-214 (STATICCALL)
:constantinopleEIP-1014 (CREATE2), EIP-145 (SHL/SHR/SAR), EIP-1052 (EXTCODEHASH)
:istanbulEIP-152 (BLAKE2F precompile), EIP-1108 (alt_bn128 repricing), EIP-1344 (CHAINID), EIP-1884 (SELFBALANCE), EIP-2028 (calldata cost), EIP-2200 (SSTORE)
:berlinEIP-2565 (ModExp repricing), EIP-2929 (cold/warm access), EIP-2930 (access lists)
:londonEIP-1559 (basefee), EIP-3198 (BASEFEE), EIP-3529 (refund cap), EIP-3541 (0xEF rejection)
:parisThe Merge (PREVRANDAO replaces DIFFICULTY)
:shanghaiEIP-3651 (COINBASE pre-warm), EIP-3855 (PUSH0), EIP-3860 (initcode limit)
:cancunEIP-1153 (TLOAD/TSTORE), EIP-4844 (blobs, BLOBHASH, KZG precompile), EIP-5656 (MCOPY), EIP-6780 (SELFDESTRUCT), EIP-7516 (BLOBBASEFEE)
:pragueEIP-2537 (BLS12-381 precompiles), EIP-7623 (calldata floor), EIP-7702 (set-code)
EIP-2935 (block hashes), EIP-7685 requests: EIP-6110 deposits, EIP-7002 withdrawals, EIP-7251 consolidations
:osakaEIP-7825 (tx gas limit cap), EIP-7918 (blob base fee floor), EIP-7934 (block RLP size limit), EIP-7939 (CLZ)
EIP-7823 (ModExp bounds), EIP-7883 (ModExp repricing), EIP-7951 (P256VERIFY precompile)
EIP-7594 (at most 6 blobs per transaction)

Summary

Functions

Returns the ordinal/1 of the fork that activates flag. Raises ArgumentError when flag isn't declared in @eip_activation.

Returns a list of all known spec IDs in chronological order.

Returns the default hardfork config — Cancun, the most-tested hardfork.

Returns whether the EIP feature flag flag is active in hardfork.

Returns whether flag is declared in @eip_activation.

Creates a new hardfork config for the given spec_id.

Returns the position of hardfork's spec in the fork order, from 0 for Frontier; enabled?/2 compares it with a flag's activation.

Types

spec_id()

@type spec_id() ::
  :frontier
  | :homestead
  | :tangerine_whistle
  | :spurious_dragon
  | :byzantium
  | :constantinople
  | :istanbul
  | :berlin
  | :london
  | :paris
  | :shanghai
  | :cancun
  | :prague
  | :osaka

t()

@type t() :: %EEVM.HardforkConfig{spec_id: spec_id()}

Functions

activation_ordinal!(flag)

@spec activation_ordinal!(atom()) :: non_neg_integer()

Returns the ordinal/1 of the fork that activates flag. Raises ArgumentError when flag isn't declared in @eip_activation.

all_spec_ids()

@spec all_spec_ids() :: [spec_id()]

Returns a list of all known spec IDs in chronological order.

default()

@spec default() :: t()

Returns the default hardfork config — Cancun, the most-tested hardfork.

Callers that don't specify a hardfork explicitly get Cancun semantics, preserving backwards compatibility with all existing tests.

enabled?(hardfork, flag)

(macro)

Returns whether the EIP feature flag flag is active in hardfork.

A macro, so require EEVM.HardforkConfig first. With a literal flag, as eevm's own code always passes, the flag is looked up when the caller compiles: a flag missing from @eip_activation, such as a misspelling, is a compile error rather than a rule that is silently off, and the check compiles to one integer comparison. A flag held in a variable must be declared too, or the check raises ArgumentError; tables of flags, like the opcode registry's, are read when the per-fork tables are built at compile time, so a bad entry fails that compilation.

EEVM.Config.enabled?/2 is the public runtime check, for which unknown flags are inactive.

Examples

iex> require EEVM.HardforkConfig
iex> EEVM.HardforkConfig.enabled?(EEVM.HardforkConfig.new(:cancun), :eip_6780)
true
iex> EEVM.HardforkConfig.enabled?(EEVM.HardforkConfig.new(:london), :eip_6780)
false
iex> flag = :eip_2929
iex> EEVM.HardforkConfig.enabled?(EEVM.HardforkConfig.new(:berlin), flag)
true

flag?(flag)

@spec flag?(atom()) :: boolean()

Returns whether flag is declared in @eip_activation.

Examples

iex> EEVM.HardforkConfig.flag?(:eip_1559)
true
iex> EEVM.HardforkConfig.flag?(:eip_1595)
false

new(spec_id)

@spec new(spec_id()) :: t()

Creates a new hardfork config for the given spec_id.

Example

iex> EEVM.HardforkConfig.new(:cancun)
%EEVM.HardforkConfig{spec_id: :cancun}

ordinal(hardfork)

@spec ordinal(t()) :: non_neg_integer()

Returns the position of hardfork's spec in the fork order, from 0 for Frontier; enabled?/2 compares it with a flag's activation.