Chain configuration¶
The decoded SszChainConfig. Its activation point is validated while decoding,
so the resulting value only carries the chain id. The schema prefix selects the
protocol profile, so neither the fork identifier nor its blob schedule is
repeated inside the SSZ body. Pure data — no registers, no externs.
type blob_fee_update_fraction_parameter¶
The base-fee update fractions used by some supported blob schedule.
type blob_fee_update_fraction_parameter('denominator : Int) -> Bool =
'denominator == inactive_blob_fee_update_fraction
| 'denominator == cancun_blob_fee_update_fraction
| 'denominator == prague_blob_fee_update_fraction
| 'denominator == bpo1_blob_fee_update_fraction
| 'denominator == bpo2_blob_fee_update_fractionThe BPO1 blob-fee update fraction.
type bpo1_blob_fee_update_fraction : Int = 8346193The BPO2 blob-fee update fraction (EIP-8135).
type bpo2_blob_fee_update_fraction : Int = 11684671Cancun's BLOB_BASE_FEE_UPDATE_FRACTION (EIP-4844).
type cancun_blob_fee_update_fraction : Int = 3338477Named EIP-4844/BPO fee-update fractions.
type inactive_blob_fee_update_fraction : Int = 1Prague's BLOB_BASE_FEE_UPDATE_FRACTION (EIP-7691).
type prague_blob_fee_update_fraction : Int = 5007716type blob_schedule_parameters¶
The five protocol-defined blob schedules. Keeping the fields related excludes cross-products of individually valid constants which are not a schedule used by any fork.
type blob_schedule_parameters(
'target : Int,
'maximum : Int,
'denominator : Int,
) -> Bool =
blob_fee_update_fraction_parameter('denominator)
& (
(
'target == blob_schedule_inactive_count
& 'maximum == blob_schedule_inactive_count
& 'denominator == inactive_blob_fee_update_fraction
)
| (
'target == cancun_blob_target_count
& 'maximum == cancun_blob_max_count
& 'denominator == cancun_blob_fee_update_fraction
)
| (
'target == prague_blob_target_count
& 'maximum == prague_blob_max_count
& 'denominator == prague_blob_fee_update_fraction
)
| (
'target == bpo1_blob_target_count
& 'maximum == bpo1_blob_max_count
& 'denominator == bpo1_blob_fee_update_fraction
)
| (
'target == bpo2_blob_target_count
& 'maximum == bpo2_blob_max_count
& 'denominator == bpo2_blob_fee_update_fraction
)
)The base-fee update fractions used by some supported blob schedule.
type blob_fee_update_fraction_parameter('denominator : Int) -> Bool =
'denominator == inactive_blob_fee_update_fraction
| 'denominator == cancun_blob_fee_update_fraction
| 'denominator == prague_blob_fee_update_fraction
| 'denominator == bpo1_blob_fee_update_fraction
| 'denominator == bpo2_blob_fee_update_fractionNamed blob-schedule constants retained by the profile domains below.
type blob_schedule_inactive_count : Int = 0The BPO1 blob-fee update fraction.
type bpo1_blob_fee_update_fraction : Int = 8346193The BPO1 per-block blob maximum of 15.
type bpo1_blob_max_count : Int = 15The BPO1 per-block blob target of 10.
type bpo1_blob_target_count : Int = 10The BPO2 blob-fee update fraction (EIP-8135).
type bpo2_blob_fee_update_fraction : Int = 11684671The BPO2 per-block blob maximum of 21.
type bpo2_blob_max_count : Int = 21The BPO2 per-block blob target of 14.
type bpo2_blob_target_count : Int = 14Cancun's BLOB_BASE_FEE_UPDATE_FRACTION (EIP-4844).
type cancun_blob_fee_update_fraction : Int = 3338477Cancun's per-block blob maximum of 6 (EIP-4844).
type cancun_blob_max_count : Int = 6Cancun's per-block blob target of 3 (EIP-4844).
type cancun_blob_target_count : Int = 3Named EIP-4844/BPO fee-update fractions.
type inactive_blob_fee_update_fraction : Int = 1Prague's BLOB_BASE_FEE_UPDATE_FRACTION (EIP-7691).
type prague_blob_fee_update_fraction : Int = 5007716Prague's per-block blob maximum of 9 (EIP-7691).
type prague_blob_max_count : Int = 9Prague's per-block blob target of 6 (EIP-7691).
type prague_blob_target_count : Int = 6type BlobScheduleFields¶
A fork's associated blob parameters (EIP-4844/EIP-7691): target and maximum blob counts per block, and the base-fee update fraction. The existential indices retain the selected schedule's equations wherever the value is consumed.
struct BlobScheduleFields('target : Int, 'maximum : Int, 'denominator : Int),
blob_schedule_parameters('target, 'maximum, 'denominator) = {
target : int('target),
max : int('maximum),
base_fee_update_fraction : int('denominator),
}The five protocol-defined blob schedules. Keeping the fields related excludes cross-products of individually valid constants which are not a schedule used by any fork.
type blob_schedule_parameters(
'target : Int,
'maximum : Int,
'denominator : Int,
) -> Bool =
blob_fee_update_fraction_parameter('denominator)
& (
(
'target == blob_schedule_inactive_count
& 'maximum == blob_schedule_inactive_count
& 'denominator == inactive_blob_fee_update_fraction
)
| (
'target == cancun_blob_target_count
& 'maximum == cancun_blob_max_count
& 'denominator == cancun_blob_fee_update_fraction
)
| (
'target == prague_blob_target_count
& 'maximum == prague_blob_max_count
& 'denominator == prague_blob_fee_update_fraction
)
| (
'target == bpo1_blob_target_count
& 'maximum == bpo1_blob_max_count
& 'denominator == bpo1_blob_fee_update_fraction
)
| (
'target == bpo2_blob_target_count
& 'maximum == bpo2_blob_max_count
& 'denominator == bpo2_blob_fee_update_fraction
)
)type BlobSchedule¶
An admitted blob schedule with its three parameters packed existentially.
type BlobSchedule = {
'target 'maximum 'denominator,
blob_schedule_parameters('target, 'maximum, 'denominator).
BlobScheduleFields('target, 'maximum, 'denominator)
}A fork's associated blob parameters (EIP-4844/EIP-7691): target and maximum blob counts per block, and the base-fee update fraction. The existential indices retain the selected schedule's equations wherever the value is consumed.
struct BlobScheduleFields('target : Int, 'maximum : Int, 'denominator : Int),
blob_schedule_parameters('target, 'maximum, 'denominator) = {
target : int('target),
max : int('maximum),
base_fee_update_fraction : int('denominator),
}The five protocol-defined blob schedules. Keeping the fields related excludes cross-products of individually valid constants which are not a schedule used by any fork.
type blob_schedule_parameters(
'target : Int,
'maximum : Int,
'denominator : Int,
) -> Bool =
blob_fee_update_fraction_parameter('denominator)
& (
(
'target == blob_schedule_inactive_count
& 'maximum == blob_schedule_inactive_count
& 'denominator == inactive_blob_fee_update_fraction
)
| (
'target == cancun_blob_target_count
& 'maximum == cancun_blob_max_count
& 'denominator == cancun_blob_fee_update_fraction
)
| (
'target == prague_blob_target_count
& 'maximum == prague_blob_max_count
& 'denominator == prague_blob_fee_update_fraction
)
| (
'target == bpo1_blob_target_count
& 'maximum == bpo1_blob_max_count
& 'denominator == bpo1_blob_fee_update_fraction
)
| (
'target == bpo2_blob_target_count
& 'maximum == bpo2_blob_max_count
& 'denominator == bpo2_blob_fee_update_fraction
)
)type cancun_blob_schedule¶
Exact active-fork schedule types. These aliases make a profile refinement visible at call sites without reconstructing or copying its schedule.
type cancun_blob_schedule = BlobScheduleFields(
cancun_blob_target_count,
cancun_blob_max_count,
cancun_blob_fee_update_fraction,
)A fork's associated blob parameters (EIP-4844/EIP-7691): target and maximum blob counts per block, and the base-fee update fraction. The existential indices retain the selected schedule's equations wherever the value is consumed.
struct BlobScheduleFields('target : Int, 'maximum : Int, 'denominator : Int),
blob_schedule_parameters('target, 'maximum, 'denominator) = {
target : int('target),
max : int('maximum),
base_fee_update_fraction : int('denominator),
}Cancun's BLOB_BASE_FEE_UPDATE_FRACTION (EIP-4844).
type cancun_blob_fee_update_fraction : Int = 3338477Cancun's per-block blob maximum of 6 (EIP-4844).
type cancun_blob_max_count : Int = 6Cancun's per-block blob target of 3 (EIP-4844).
type cancun_blob_target_count : Int = 3type prague_blob_schedule¶
The exact schedule type of the Prague fork (EIP-7691).
type prague_blob_schedule = BlobScheduleFields(
prague_blob_target_count,
prague_blob_max_count,
prague_blob_fee_update_fraction,
)A fork's associated blob parameters (EIP-4844/EIP-7691): target and maximum blob counts per block, and the base-fee update fraction. The existential indices retain the selected schedule's equations wherever the value is consumed.
struct BlobScheduleFields('target : Int, 'maximum : Int, 'denominator : Int),
blob_schedule_parameters('target, 'maximum, 'denominator) = {
target : int('target),
max : int('maximum),
base_fee_update_fraction : int('denominator),
}Prague's BLOB_BASE_FEE_UPDATE_FRACTION (EIP-7691).
type prague_blob_fee_update_fraction : Int = 5007716Prague's per-block blob maximum of 9 (EIP-7691).
type prague_blob_max_count : Int = 9Prague's per-block blob target of 6 (EIP-7691).
type prague_blob_target_count : Int = 6type osaka_blob_schedule¶
The exact schedule type of the Osaka fork, which retains Prague's blob parameters.
type osaka_blob_schedule = BlobScheduleFields(
prague_blob_target_count,
prague_blob_max_count,
prague_blob_fee_update_fraction,
)A fork's associated blob parameters (EIP-4844/EIP-7691): target and maximum blob counts per block, and the base-fee update fraction. The existential indices retain the selected schedule's equations wherever the value is consumed.
struct BlobScheduleFields('target : Int, 'maximum : Int, 'denominator : Int),
blob_schedule_parameters('target, 'maximum, 'denominator) = {
target : int('target),
max : int('maximum),
base_fee_update_fraction : int('denominator),
}Prague's BLOB_BASE_FEE_UPDATE_FRACTION (EIP-7691).
type prague_blob_fee_update_fraction : Int = 5007716Prague's per-block blob maximum of 9 (EIP-7691).
type prague_blob_max_count : Int = 9Prague's per-block blob target of 6 (EIP-7691).
type prague_blob_target_count : Int = 6type bpo1_blob_schedule¶
The exact schedule type of the first blob-parameter-only fork.
type bpo1_blob_schedule = BlobScheduleFields(
bpo1_blob_target_count,
bpo1_blob_max_count,
bpo1_blob_fee_update_fraction,
)A fork's associated blob parameters (EIP-4844/EIP-7691): target and maximum blob counts per block, and the base-fee update fraction. The existential indices retain the selected schedule's equations wherever the value is consumed.
struct BlobScheduleFields('target : Int, 'maximum : Int, 'denominator : Int),
blob_schedule_parameters('target, 'maximum, 'denominator) = {
target : int('target),
max : int('maximum),
base_fee_update_fraction : int('denominator),
}The BPO1 blob-fee update fraction.
type bpo1_blob_fee_update_fraction : Int = 8346193The BPO1 per-block blob maximum of 15.
type bpo1_blob_max_count : Int = 15The BPO1 per-block blob target of 10.
type bpo1_blob_target_count : Int = 10type bpo2_blob_schedule¶
The exact schedule type of the second blob-parameter-only fork.
type bpo2_blob_schedule = BlobScheduleFields(
bpo2_blob_target_count,
bpo2_blob_max_count,
bpo2_blob_fee_update_fraction,
)A fork's associated blob parameters (EIP-4844/EIP-7691): target and maximum blob counts per block, and the base-fee update fraction. The existential indices retain the selected schedule's equations wherever the value is consumed.
struct BlobScheduleFields('target : Int, 'maximum : Int, 'denominator : Int),
blob_schedule_parameters('target, 'maximum, 'denominator) = {
target : int('target),
max : int('maximum),
base_fee_update_fraction : int('denominator),
}The BPO2 blob-fee update fraction (EIP-8135).
type bpo2_blob_fee_update_fraction : Int = 11684671The BPO2 per-block blob maximum of 21.
type bpo2_blob_max_count : Int = 21The BPO2 per-block blob target of 14.
type bpo2_blob_target_count : Int = 14type amsterdam_blob_schedule¶
The exact schedule type of the Amsterdam fork, which retains BPO2's blob parameters.
type amsterdam_blob_schedule = BlobScheduleFields(
bpo2_blob_target_count,
bpo2_blob_max_count,
bpo2_blob_fee_update_fraction,
)A fork's associated blob parameters (EIP-4844/EIP-7691): target and maximum blob counts per block, and the base-fee update fraction. The existential indices retain the selected schedule's equations wherever the value is consumed.
struct BlobScheduleFields('target : Int, 'maximum : Int, 'denominator : Int),
blob_schedule_parameters('target, 'maximum, 'denominator) = {
target : int('target),
max : int('maximum),
base_fee_update_fraction : int('denominator),
}The BPO2 blob-fee update fraction (EIP-8135).
type bpo2_blob_fee_update_fraction : Int = 11684671The BPO2 per-block blob maximum of 21.
type bpo2_blob_max_count : Int = 21The BPO2 per-block blob target of 14.
type bpo2_blob_target_count : Int = 14function blob_schedule¶
function blob_schedule(target, maximum, denominator) =
struct { target = target, max = maximum, base_fee_update_fraction = denominator }function blob_schedule(target, maximum, denominator) =
struct { target = target, max = maximum, base_fee_update_fraction = denominator }type protocol_profile_parameters¶
The protocol parameter tuples admitted by supported forks. Keeping the fields under one constraint preserves their relationships: consumers know that they received one real protocol profile rather than an arbitrary cross-product of individually valid constants.
type protocol_profile_parameters(
'fork : Int,
'target : Int,
'maximum : Int,
'denominator : Int,
'code_limit : Int,
'initcode_limit : Int,
'transaction_total_gas_limit : Int,
'transaction_regular_gas_limit : Int,
'transaction_blob_limit : Int,
'refund_divisor : Int,
) -> Bool =
(
'fork == berlin_fork_value
& 'target == blob_schedule_inactive_count
& 'maximum == blob_schedule_inactive_count
& 'denominator == inactive_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == inactive_initcode_size_limit
& 'transaction_total_gas_limit == ssz_uint_bound
& 'transaction_regular_gas_limit == ssz_uint_bound
& 'transaction_blob_limit == blob_schedule_inactive_count
& 'refund_divisor == pre_london_refund_divisor
)
| (
(
london_fork_value <= 'fork
& 'fork <= paris_fork_value
)
& 'target == blob_schedule_inactive_count
& 'maximum == blob_schedule_inactive_count
& 'denominator == inactive_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == inactive_initcode_size_limit
& 'transaction_total_gas_limit == ssz_uint_bound
& 'transaction_regular_gas_limit == ssz_uint_bound
& 'transaction_blob_limit == blob_schedule_inactive_count
& 'refund_divisor == post_london_refund_divisor
)
| (
'fork == shanghai_fork_value
& 'target == blob_schedule_inactive_count
& 'maximum == blob_schedule_inactive_count
& 'denominator == inactive_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == pre_amsterdam_initcode_size_limit
& 'transaction_total_gas_limit == ssz_uint_bound
& 'transaction_regular_gas_limit == ssz_uint_bound
& 'transaction_blob_limit == blob_schedule_inactive_count
& 'refund_divisor == post_london_refund_divisor
)
| (
'fork == first_blob_fork_value
& 'target == cancun_blob_target_count
& 'maximum == cancun_blob_max_count
& 'denominator == cancun_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == pre_amsterdam_initcode_size_limit
& 'transaction_total_gas_limit == ssz_uint_bound
& 'transaction_regular_gas_limit == ssz_uint_bound
& 'transaction_blob_limit == cancun_blob_max_count
& 'refund_divisor == post_london_refund_divisor
)
| (
'fork == prague_fork_value
& 'target == prague_blob_target_count
& 'maximum == prague_blob_max_count
& 'denominator == prague_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == pre_amsterdam_initcode_size_limit
& 'transaction_total_gas_limit == ssz_uint_bound
& 'transaction_regular_gas_limit == ssz_uint_bound
& 'transaction_blob_limit == prague_blob_max_count
& 'refund_divisor == post_london_refund_divisor
)
| (
'fork == osaka_fork_value
& 'target == prague_blob_target_count
& 'maximum == prague_blob_max_count
& 'denominator == prague_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == pre_amsterdam_initcode_size_limit
& 'transaction_total_gas_limit == eip7825_transaction_gas_limit
& 'transaction_regular_gas_limit == eip7825_transaction_gas_limit
& 'transaction_blob_limit == cancun_blob_max_count
& 'refund_divisor == post_london_refund_divisor
)
| (
'fork == bpo1_fork_value
& 'target == bpo1_blob_target_count
& 'maximum == bpo1_blob_max_count
& 'denominator == bpo1_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == pre_amsterdam_initcode_size_limit
& 'transaction_total_gas_limit == eip7825_transaction_gas_limit
& 'transaction_regular_gas_limit == eip7825_transaction_gas_limit
& 'transaction_blob_limit == cancun_blob_max_count
& 'refund_divisor == post_london_refund_divisor
)
| (
'fork == bpo2_fork_value
& 'target == bpo2_blob_target_count
& 'maximum == bpo2_blob_max_count
& 'denominator == bpo2_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == pre_amsterdam_initcode_size_limit
& 'transaction_total_gas_limit == eip7825_transaction_gas_limit
& 'transaction_regular_gas_limit == eip7825_transaction_gas_limit
& 'transaction_blob_limit == cancun_blob_max_count
& 'refund_divisor == post_london_refund_divisor
)
| (
'fork == amsterdam_fork_value
& 'target == bpo2_blob_target_count
& 'maximum == bpo2_blob_max_count
& 'denominator == bpo2_blob_fee_update_fraction
& 'code_limit == amsterdam_deployed_code_size_limit
& 'initcode_limit == amsterdam_initcode_size_limit
& 'transaction_total_gas_limit == ssz_uint_bound
& 'transaction_regular_gas_limit == eip7825_transaction_gas_limit
& 'transaction_blob_limit == cancun_blob_max_count
& 'refund_divisor == post_london_refund_divisor
)Amsterdam's raised deployed-code size limit of 65,536 bytes.
type amsterdam_deployed_code_size_limit : Int = 65536Amsterdam's position in the activation order.
type amsterdam_fork_value : Int = 16Amsterdam's raised initcode size limit of 131,072 bytes.
type amsterdam_initcode_size_limit : Int = 131072Berlin's position in the activation order.
type berlin_fork_value : Int = 5Named blob-schedule constants retained by the profile domains below.
type blob_schedule_inactive_count : Int = 0The BPO1 blob-fee update fraction.
type bpo1_blob_fee_update_fraction : Int = 8346193The BPO1 per-block blob maximum of 15.
type bpo1_blob_max_count : Int = 15The BPO1 per-block blob target of 10.
type bpo1_blob_target_count : Int = 10BPO1's position in the activation order.
type bpo1_fork_value : Int = 14The BPO2 blob-fee update fraction (EIP-8135).
type bpo2_blob_fee_update_fraction : Int = 11684671The BPO2 per-block blob maximum of 21.
type bpo2_blob_max_count : Int = 21The BPO2 per-block blob target of 14.
type bpo2_blob_target_count : Int = 14BPO2's position in the activation order.
type bpo2_fork_value : Int = 15Cancun's BLOB_BASE_FEE_UPDATE_FRACTION (EIP-4844).
type cancun_blob_fee_update_fraction : Int = 3338477Cancun's per-block blob maximum of 6 (EIP-4844).
type cancun_blob_max_count : Int = 6Cancun's per-block blob target of 3 (EIP-4844).
type cancun_blob_target_count : Int = 3The EIP-7825 per-transaction gas cap of 2^24.
type eip7825_transaction_gas_limit : Int = 2 ^ 24First fork at which blob gas is active. Kept as a type-level singleton so
profile equations and the runtime Cancun value share one boundary.
type first_blob_fork_value : Int = 11Named EIP-4844/BPO fee-update fractions.
type inactive_blob_fee_update_fraction : Int = 1The zero initcode limit for profiles before EIP-3860 activates.
type inactive_initcode_size_limit : Int = 0London's position in the activation order.
type london_fork_value : Int = 6Osaka's position in the activation order.
type osaka_fork_value : Int = 13Paris's position in the activation order.
type paris_fork_value : Int = 9The London refund divisor: EIP-3529 caps refunds at gas_used / 5.
type post_london_refund_divisor : Int = 5Prague's BLOB_BASE_FEE_UPDATE_FRACTION (EIP-7691).
type prague_blob_fee_update_fraction : Int = 5007716Prague's per-block blob maximum of 9 (EIP-7691).
type prague_blob_max_count : Int = 9Prague's per-block blob target of 6 (EIP-7691).
type prague_blob_target_count : Int = 6Prague's position in the activation order.
type prague_fork_value : Int = 12Fork-selected limits retained in the validated protocol profile. A fork
without a stricter transaction-gas cap admits the complete SSZ uint64
block-gas domain; the concrete header limit is applied separately.
type pre_amsterdam_deployed_code_size_limit : Int = 24576The EIP-3860 initcode size limit of 49,152 bytes.
type pre_amsterdam_initcode_size_limit : Int = 49152The pre-London refund divisor: refunds are capped at gas_used / 2.
type pre_london_refund_divisor : Int = 2Shanghai's position in the activation order.
type shanghai_fork_value : Int = 10Largest value represented by an SSZ uint64. This is a wire-schema
constraint, sourced from the consensus ExecutionPayload container and
the Amsterdam SszExecutionPayload, rather than an implementation word
size.
type ssz_uint_bound : Int = 2 ^ 64 - 1type profile_excess_blob_gas_limit¶
The reachable excess-blob-gas ceiling derived from a correlated profile. The type-level equation is also the field's singleton type, so the stored value cannot disagree with its fork or schedule.
type profile_excess_blob_gas_limit(
'fork : Int,
'target : Int,
'maximum : Int,
'denominator : Int,
) = int(
if 'fork < first_blob_fork_value then
0
else
blob_fee_word_exponent_limit * 'denominator
+ ('maximum - 'target) * gas_per_blob_value
)A conservative exponent at which an EIP-4844 blob base fee can no longer
fit in the EVM's 256-bit word domain: e^256 > 2^256.
type blob_fee_word_exponent_limit : Int = 256First fork at which blob gas is active. Kept as a type-level singleton so
profile equations and the runtime Cancun value share one boundary.
type first_blob_fork_value : Int = 11Blob gas charged per blob, 2^17 (EIP-4844).
type gas_per_blob_value : Int = 2 ^ 17function compute_profile_excess_blob_gas_limit¶
function compute_profile_excess_blob_gas_limit(fork, target, maximum, denominator) =
if fork < Cancun then {
0
} else {
sizeof(blob_fee_word_exponent_limit) * denominator + (maximum - target) * sizeof(gas_per_blob_value)
}function compute_profile_excess_blob_gas_limit(fork, target, maximum, denominator) =
if fork < Cancun then {
0
} else {
sizeof(blob_fee_word_exponent_limit) * denominator + (maximum - target) * sizeof(gas_per_blob_value)
}EIP-1153/4844; precompiles 0x01-0x0a.
let Cancun : int(first_blob_fork_value) = sizeof(first_blob_fork_value)A conservative exponent at which an EIP-4844 blob base fee can no longer
fit in the EVM's 256-bit word domain: e^256 > 2^256.
type blob_fee_word_exponent_limit : Int = 256Blob gas charged per blob, 2^17 (EIP-4844).
type gas_per_blob_value : Int = 2 ^ 17type ProtocolProfileFields¶
Execution rules and computation bounds selected together by one schema fork. The singleton indices retain the exact selected parameter tuple.
struct ProtocolProfileFields(
'fork : Int,
'target : Int,
'maximum : Int,
'denominator : Int,
'code_limit : Int,
'initcode_limit : Int,
'transaction_total_gas_limit : Int,
'transaction_regular_gas_limit : Int,
'transaction_blob_limit : Int,
'refund_divisor : Int,
), protocol_profile_parameters(
'fork,
'target,
'maximum,
'denominator,
'code_limit,
'initcode_limit,
'transaction_total_gas_limit,
'transaction_regular_gas_limit,
'transaction_blob_limit,
'refund_divisor,
) = {
fork : int('fork),
blob_schedule : BlobScheduleFields('target, 'maximum, 'denominator),
excess_blob_gas_limit : profile_excess_blob_gas_limit(
'fork,
'target,
'maximum,
'denominator,
),
deployed_code_size_limit : int('code_limit),
initcode_size_limit : int('initcode_limit),
transaction_total_gas_limit : int('transaction_total_gas_limit),
transaction_regular_gas_limit : int('transaction_regular_gas_limit),
transaction_blob_limit : int('transaction_blob_limit),
refund_divisor : int('refund_divisor),
}function blob_schedule(target, maximum, denominator) =
struct { target = target, max = maximum, base_fee_update_fraction = denominator }A fork's associated blob parameters (EIP-4844/EIP-7691): target and maximum blob counts per block, and the base-fee update fraction. The existential indices retain the selected schedule's equations wherever the value is consumed.
struct BlobScheduleFields('target : Int, 'maximum : Int, 'denominator : Int),
blob_schedule_parameters('target, 'maximum, 'denominator) = {
target : int('target),
max : int('maximum),
base_fee_update_fraction : int('denominator),
}The reachable excess-blob-gas ceiling derived from a correlated profile. The type-level equation is also the field's singleton type, so the stored value cannot disagree with its fork or schedule.
type profile_excess_blob_gas_limit(
'fork : Int,
'target : Int,
'maximum : Int,
'denominator : Int,
) = int(
if 'fork < first_blob_fork_value then
0
else
blob_fee_word_exponent_limit * 'denominator
+ ('maximum - 'target) * gas_per_blob_value
)The protocol parameter tuples admitted by supported forks. Keeping the fields under one constraint preserves their relationships: consumers know that they received one real protocol profile rather than an arbitrary cross-product of individually valid constants.
type protocol_profile_parameters(
'fork : Int,
'target : Int,
'maximum : Int,
'denominator : Int,
'code_limit : Int,
'initcode_limit : Int,
'transaction_total_gas_limit : Int,
'transaction_regular_gas_limit : Int,
'transaction_blob_limit : Int,
'refund_divisor : Int,
) -> Bool =
(
'fork == berlin_fork_value
& 'target == blob_schedule_inactive_count
& 'maximum == blob_schedule_inactive_count
& 'denominator == inactive_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == inactive_initcode_size_limit
& 'transaction_total_gas_limit == ssz_uint_bound
& 'transaction_regular_gas_limit == ssz_uint_bound
& 'transaction_blob_limit == blob_schedule_inactive_count
& 'refund_divisor == pre_london_refund_divisor
)
| (
(
london_fork_value <= 'fork
& 'fork <= paris_fork_value
)
& 'target == blob_schedule_inactive_count
& 'maximum == blob_schedule_inactive_count
& 'denominator == inactive_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == inactive_initcode_size_limit
& 'transaction_total_gas_limit == ssz_uint_bound
& 'transaction_regular_gas_limit == ssz_uint_bound
& 'transaction_blob_limit == blob_schedule_inactive_count
& 'refund_divisor == post_london_refund_divisor
)
| (
'fork == shanghai_fork_value
& 'target == blob_schedule_inactive_count
& 'maximum == blob_schedule_inactive_count
& 'denominator == inactive_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == pre_amsterdam_initcode_size_limit
& 'transaction_total_gas_limit == ssz_uint_bound
& 'transaction_regular_gas_limit == ssz_uint_bound
& 'transaction_blob_limit == blob_schedule_inactive_count
& 'refund_divisor == post_london_refund_divisor
)
| (
'fork == first_blob_fork_value
& 'target == cancun_blob_target_count
& 'maximum == cancun_blob_max_count
& 'denominator == cancun_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == pre_amsterdam_initcode_size_limit
& 'transaction_total_gas_limit == ssz_uint_bound
& 'transaction_regular_gas_limit == ssz_uint_bound
& 'transaction_blob_limit == cancun_blob_max_count
& 'refund_divisor == post_london_refund_divisor
)
| (
'fork == prague_fork_value
& 'target == prague_blob_target_count
& 'maximum == prague_blob_max_count
& 'denominator == prague_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == pre_amsterdam_initcode_size_limit
& 'transaction_total_gas_limit == ssz_uint_bound
& 'transaction_regular_gas_limit == ssz_uint_bound
& 'transaction_blob_limit == prague_blob_max_count
& 'refund_divisor == post_london_refund_divisor
)
| (
'fork == osaka_fork_value
& 'target == prague_blob_target_count
& 'maximum == prague_blob_max_count
& 'denominator == prague_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == pre_amsterdam_initcode_size_limit
& 'transaction_total_gas_limit == eip7825_transaction_gas_limit
& 'transaction_regular_gas_limit == eip7825_transaction_gas_limit
& 'transaction_blob_limit == cancun_blob_max_count
& 'refund_divisor == post_london_refund_divisor
)
| (
'fork == bpo1_fork_value
& 'target == bpo1_blob_target_count
& 'maximum == bpo1_blob_max_count
& 'denominator == bpo1_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == pre_amsterdam_initcode_size_limit
& 'transaction_total_gas_limit == eip7825_transaction_gas_limit
& 'transaction_regular_gas_limit == eip7825_transaction_gas_limit
& 'transaction_blob_limit == cancun_blob_max_count
& 'refund_divisor == post_london_refund_divisor
)
| (
'fork == bpo2_fork_value
& 'target == bpo2_blob_target_count
& 'maximum == bpo2_blob_max_count
& 'denominator == bpo2_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == pre_amsterdam_initcode_size_limit
& 'transaction_total_gas_limit == eip7825_transaction_gas_limit
& 'transaction_regular_gas_limit == eip7825_transaction_gas_limit
& 'transaction_blob_limit == cancun_blob_max_count
& 'refund_divisor == post_london_refund_divisor
)
| (
'fork == amsterdam_fork_value
& 'target == bpo2_blob_target_count
& 'maximum == bpo2_blob_max_count
& 'denominator == bpo2_blob_fee_update_fraction
& 'code_limit == amsterdam_deployed_code_size_limit
& 'initcode_limit == amsterdam_initcode_size_limit
& 'transaction_total_gas_limit == ssz_uint_bound
& 'transaction_regular_gas_limit == eip7825_transaction_gas_limit
…A fork-selected per-transaction blob limit drawn from the supported schedules; zero for profiles before blob transactions activate.
type transaction_blob_limit = {
'value,
transaction_blob_limit_value('value).
int('value)
}type ProtocolProfile¶
A protocol profile with its parameter tuple packed existentially; unpacking recovers the admitted combination's equations.
type ProtocolProfile = {
'fork
'target
'maximum
'denominator
'code_limit
'initcode_limit
'transaction_total_gas_limit
'transaction_regular_gas_limit
'transaction_blob_limit
'refund_divisor,
protocol_profile_parameters(
'fork,
'target,
'maximum,
'denominator,
'code_limit,
'initcode_limit,
'transaction_total_gas_limit,
'transaction_regular_gas_limit,
'transaction_blob_limit,
'refund_divisor,
).
ProtocolProfileFields(
'fork,
'target,
'maximum,
'denominator,
'code_limit,
'initcode_limit,
'transaction_total_gas_limit,
'transaction_regular_gas_limit,
'transaction_blob_limit,
'refund_divisor,
)
}Execution rules and computation bounds selected together by one schema fork. The singleton indices retain the exact selected parameter tuple.
struct ProtocolProfileFields(
'fork : Int,
'target : Int,
'maximum : Int,
'denominator : Int,
'code_limit : Int,
'initcode_limit : Int,
'transaction_total_gas_limit : Int,
'transaction_regular_gas_limit : Int,
'transaction_blob_limit : Int,
'refund_divisor : Int,
), protocol_profile_parameters(
'fork,
'target,
'maximum,
'denominator,
'code_limit,
'initcode_limit,
'transaction_total_gas_limit,
'transaction_regular_gas_limit,
'transaction_blob_limit,
'refund_divisor,
) = {
fork : int('fork),
blob_schedule : BlobScheduleFields('target, 'maximum, 'denominator),
excess_blob_gas_limit : profile_excess_blob_gas_limit(
'fork,
'target,
'maximum,
'denominator,
),
deployed_code_size_limit : int('code_limit),
initcode_size_limit : int('initcode_limit),
transaction_total_gas_limit : int('transaction_total_gas_limit),
transaction_regular_gas_limit : int('transaction_regular_gas_limit),
transaction_blob_limit : int('transaction_blob_limit),
refund_divisor : int('refund_divisor),
}The protocol parameter tuples admitted by supported forks. Keeping the fields under one constraint preserves their relationships: consumers know that they received one real protocol profile rather than an arbitrary cross-product of individually valid constants.
type protocol_profile_parameters(
'fork : Int,
'target : Int,
'maximum : Int,
'denominator : Int,
'code_limit : Int,
'initcode_limit : Int,
'transaction_total_gas_limit : Int,
'transaction_regular_gas_limit : Int,
'transaction_blob_limit : Int,
'refund_divisor : Int,
) -> Bool =
(
'fork == berlin_fork_value
& 'target == blob_schedule_inactive_count
& 'maximum == blob_schedule_inactive_count
& 'denominator == inactive_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == inactive_initcode_size_limit
& 'transaction_total_gas_limit == ssz_uint_bound
& 'transaction_regular_gas_limit == ssz_uint_bound
& 'transaction_blob_limit == blob_schedule_inactive_count
& 'refund_divisor == pre_london_refund_divisor
)
| (
(
london_fork_value <= 'fork
& 'fork <= paris_fork_value
)
& 'target == blob_schedule_inactive_count
& 'maximum == blob_schedule_inactive_count
& 'denominator == inactive_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == inactive_initcode_size_limit
& 'transaction_total_gas_limit == ssz_uint_bound
& 'transaction_regular_gas_limit == ssz_uint_bound
& 'transaction_blob_limit == blob_schedule_inactive_count
& 'refund_divisor == post_london_refund_divisor
)
| (
'fork == shanghai_fork_value
& 'target == blob_schedule_inactive_count
& 'maximum == blob_schedule_inactive_count
& 'denominator == inactive_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == pre_amsterdam_initcode_size_limit
& 'transaction_total_gas_limit == ssz_uint_bound
& 'transaction_regular_gas_limit == ssz_uint_bound
& 'transaction_blob_limit == blob_schedule_inactive_count
& 'refund_divisor == post_london_refund_divisor
)
| (
'fork == first_blob_fork_value
& 'target == cancun_blob_target_count
& 'maximum == cancun_blob_max_count
& 'denominator == cancun_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == pre_amsterdam_initcode_size_limit
& 'transaction_total_gas_limit == ssz_uint_bound
& 'transaction_regular_gas_limit == ssz_uint_bound
& 'transaction_blob_limit == cancun_blob_max_count
& 'refund_divisor == post_london_refund_divisor
)
| (
'fork == prague_fork_value
& 'target == prague_blob_target_count
& 'maximum == prague_blob_max_count
& 'denominator == prague_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == pre_amsterdam_initcode_size_limit
& 'transaction_total_gas_limit == ssz_uint_bound
& 'transaction_regular_gas_limit == ssz_uint_bound
& 'transaction_blob_limit == prague_blob_max_count
& 'refund_divisor == post_london_refund_divisor
)
| (
'fork == osaka_fork_value
& 'target == prague_blob_target_count
& 'maximum == prague_blob_max_count
& 'denominator == prague_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == pre_amsterdam_initcode_size_limit
& 'transaction_total_gas_limit == eip7825_transaction_gas_limit
& 'transaction_regular_gas_limit == eip7825_transaction_gas_limit
& 'transaction_blob_limit == cancun_blob_max_count
& 'refund_divisor == post_london_refund_divisor
)
| (
'fork == bpo1_fork_value
& 'target == bpo1_blob_target_count
& 'maximum == bpo1_blob_max_count
& 'denominator == bpo1_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == pre_amsterdam_initcode_size_limit
& 'transaction_total_gas_limit == eip7825_transaction_gas_limit
& 'transaction_regular_gas_limit == eip7825_transaction_gas_limit
& 'transaction_blob_limit == cancun_blob_max_count
& 'refund_divisor == post_london_refund_divisor
)
| (
'fork == bpo2_fork_value
& 'target == bpo2_blob_target_count
& 'maximum == bpo2_blob_max_count
& 'denominator == bpo2_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == pre_amsterdam_initcode_size_limit
& 'transaction_total_gas_limit == eip7825_transaction_gas_limit
& 'transaction_regular_gas_limit == eip7825_transaction_gas_limit
& 'transaction_blob_limit == cancun_blob_max_count
& 'refund_divisor == post_london_refund_divisor
)
| (
'fork == amsterdam_fork_value
& 'target == bpo2_blob_target_count
& 'maximum == bpo2_blob_max_count
& 'denominator == bpo2_blob_fee_update_fraction
& 'code_limit == amsterdam_deployed_code_size_limit
& 'initcode_limit == amsterdam_initcode_size_limit
& 'transaction_total_gas_limit == ssz_uint_bound
& 'transaction_regular_gas_limit == eip7825_transaction_gas_limit
…function pack_protocol_profile¶
function pack_protocol_profile(profile) = profilefunction pack_protocol_profile(profile) = profiletype gas_limits_parameters¶
The gas limits which become concrete once a correlated protocol profile
is paired with the executing block header. transaction_total_limit
bounds the transaction's complete reservoir; transaction_regular_limit
bounds the regular-execution part of that reservoir. Receipt accumulation
is indexed directly by the two block reservoirs and therefore needs no
duplicate scalar limit here.
type gas_limits_parameters(
'block_limit : Int,
'profile_total_limit : Int,
'profile_regular_limit : Int,
'transaction_total_limit : Int,
'transaction_regular_limit : Int,
) -> Bool =
0 <= 'block_limit
& 'block_limit <= block_gas_limit_bound
& protocol_transaction_total_gas_limit_value('profile_total_limit)
& protocol_transaction_regular_gas_limit_value('profile_regular_limit)
& 'transaction_total_limit
== (if 'block_limit < 'profile_total_limit then
'block_limit
else
'profile_total_limit)
& 'transaction_regular_limit
== (if 'transaction_total_limit < 'profile_regular_limit then
'transaction_total_limit
else
'profile_regular_limit)The maximum block gas limit admitted by the execution-payload SSZ
uint64 field. Provenance: consensus ExecutionPayload.gas_limit and
Amsterdam SszExecutionPayload.gas_limit.
type block_gas_limit_bound : Int = ssz_uint_boundWhether a value is a supported per-transaction regular-gas ceiling: the EIP-7825 cap or the unrestricted SSZ block-gas domain.
type protocol_transaction_regular_gas_limit_value('value : Int) -> Bool =
'value == eip7825_transaction_gas_limit
| 'value == ssz_uint_boundWhether a value is a supported per-transaction total-gas ceiling: the EIP-7825 cap or the unrestricted SSZ block-gas domain.
type protocol_transaction_total_gas_limit_value('value : Int) -> Bool =
'value == eip7825_transaction_gas_limit
| 'value == ssz_uint_boundtype GasLimitsFields¶
The concrete gas ceilings for the executing block: the header's block limit, the derived per-transaction total and regular limits, and the fixed system-call limits.
struct GasLimitsFields(
'block_limit : Int,
'profile_total_limit : Int,
'profile_regular_limit : Int,
'transaction_total_limit : Int,
'transaction_regular_limit : Int,
), gas_limits_parameters(
'block_limit,
'profile_total_limit,
'profile_regular_limit,
'transaction_total_limit,
'transaction_regular_limit,
) = {
block_limit : int('block_limit),
transaction_total_limit : int('transaction_total_limit),
transaction_regular_limit : int('transaction_regular_limit),
system_regular_limit : int(30000000),
system_state_limit : int(0),
}The gas limits which become concrete once a correlated protocol profile
is paired with the executing block header. transaction_total_limit
bounds the transaction's complete reservoir; transaction_regular_limit
bounds the regular-execution part of that reservoir. Receipt accumulation
is indexed directly by the two block reservoirs and therefore needs no
duplicate scalar limit here.
type gas_limits_parameters(
'block_limit : Int,
'profile_total_limit : Int,
'profile_regular_limit : Int,
'transaction_total_limit : Int,
'transaction_regular_limit : Int,
) -> Bool =
0 <= 'block_limit
& 'block_limit <= block_gas_limit_bound
& protocol_transaction_total_gas_limit_value('profile_total_limit)
& protocol_transaction_regular_gas_limit_value('profile_regular_limit)
& 'transaction_total_limit
== (if 'block_limit < 'profile_total_limit then
'block_limit
else
'profile_total_limit)
& 'transaction_regular_limit
== (if 'transaction_total_limit < 'profile_regular_limit then
'transaction_total_limit
else
'profile_regular_limit)type GasLimits¶
Gas limits with their five indices packed existentially.
type GasLimits = {
'block_limit
'profile_total_limit
'profile_regular_limit
'transaction_total_limit
'transaction_regular_limit,
gas_limits_parameters(
'block_limit,
'profile_total_limit,
'profile_regular_limit,
'transaction_total_limit,
'transaction_regular_limit,
).
GasLimitsFields(
'block_limit,
'profile_total_limit,
'profile_regular_limit,
'transaction_total_limit,
'transaction_regular_limit,
)
}The concrete gas ceilings for the executing block: the header's block limit, the derived per-transaction total and regular limits, and the fixed system-call limits.
struct GasLimitsFields(
'block_limit : Int,
'profile_total_limit : Int,
'profile_regular_limit : Int,
'transaction_total_limit : Int,
'transaction_regular_limit : Int,
), gas_limits_parameters(
'block_limit,
'profile_total_limit,
'profile_regular_limit,
'transaction_total_limit,
'transaction_regular_limit,
) = {
block_limit : int('block_limit),
transaction_total_limit : int('transaction_total_limit),
transaction_regular_limit : int('transaction_regular_limit),
system_regular_limit : int(30000000),
system_state_limit : int(0),
}The gas limits which become concrete once a correlated protocol profile
is paired with the executing block header. transaction_total_limit
bounds the transaction's complete reservoir; transaction_regular_limit
bounds the regular-execution part of that reservoir. Receipt accumulation
is indexed directly by the two block reservoirs and therefore needs no
duplicate scalar limit here.
type gas_limits_parameters(
'block_limit : Int,
'profile_total_limit : Int,
'profile_regular_limit : Int,
'transaction_total_limit : Int,
'transaction_regular_limit : Int,
) -> Bool =
0 <= 'block_limit
& 'block_limit <= block_gas_limit_bound
& protocol_transaction_total_gas_limit_value('profile_total_limit)
& protocol_transaction_regular_gas_limit_value('profile_regular_limit)
& 'transaction_total_limit
== (if 'block_limit < 'profile_total_limit then
'block_limit
else
'profile_total_limit)
& 'transaction_regular_limit
== (if 'transaction_total_limit < 'profile_regular_limit then
'transaction_total_limit
else
'profile_regular_limit)function gas_limits_for¶
function gas_limits_for(profile, block_limit) = {
let transaction_total_limit =
if block_limit < profile.transaction_total_gas_limit then block_limit else profile.transaction_total_gas_limit;
let transaction_regular_limit =
if transaction_total_limit < profile.transaction_regular_gas_limit
then transaction_total_limit
else profile.transaction_regular_gas_limit;
struct {
block_limit = block_limit,
transaction_total_limit = transaction_total_limit,
transaction_regular_limit = transaction_regular_limit,
system_regular_limit = SYSTEM_CALL_GAS_LIMIT,
system_state_limit = 0,
}
}function gas_limits_for(profile, block_limit) = {
let transaction_total_limit =
if block_limit < profile.transaction_total_gas_limit then block_limit else profile.transaction_total_gas_limit;
let transaction_regular_limit =
if transaction_total_limit < profile.transaction_regular_gas_limit
then transaction_total_limit
else profile.transaction_regular_gas_limit;
struct {
block_limit = block_limit,
transaction_total_limit = transaction_total_limit,
transaction_regular_limit = transaction_regular_limit,
system_regular_limit = SYSTEM_CALL_GAS_LIMIT,
system_state_limit = 0,
}
}The execution-gas allowance of each protocol system call (EIP-4788, EIP-2935, EIP-7002, EIP-7251, and EIP-8282).
let SYSTEM_CALL_GAS_LIMIT : int(30000000) = 30000000type execution_profile_parameters¶
A static protocol profile and the concrete limits derived from the current
header, indexed together. Sharing the profile indices with GasLimits
prevents independently valid but mutually inconsistent values from being
paired.
type execution_profile_parameters(
'fork : Int,
'target : Int,
'maximum : Int,
'denominator : Int,
'code_limit : Int,
'initcode_limit : Int,
'profile_total_limit : Int,
'profile_regular_limit : Int,
'transaction_blob_limit : Int,
'refund_divisor : Int,
'block_limit : Int,
'transaction_total_limit : Int,
'transaction_regular_limit : Int,
) -> Bool =
protocol_profile_parameters(
'fork,
'target,
'maximum,
'denominator,
'code_limit,
'initcode_limit,
'profile_total_limit,
'profile_regular_limit,
'transaction_blob_limit,
'refund_divisor,
)
& gas_limits_parameters(
'block_limit,
'profile_total_limit,
'profile_regular_limit,
'transaction_total_limit,
'transaction_regular_limit,
)The gas limits which become concrete once a correlated protocol profile
is paired with the executing block header. transaction_total_limit
bounds the transaction's complete reservoir; transaction_regular_limit
bounds the regular-execution part of that reservoir. Receipt accumulation
is indexed directly by the two block reservoirs and therefore needs no
duplicate scalar limit here.
type gas_limits_parameters(
'block_limit : Int,
'profile_total_limit : Int,
'profile_regular_limit : Int,
'transaction_total_limit : Int,
'transaction_regular_limit : Int,
) -> Bool =
0 <= 'block_limit
& 'block_limit <= block_gas_limit_bound
& protocol_transaction_total_gas_limit_value('profile_total_limit)
& protocol_transaction_regular_gas_limit_value('profile_regular_limit)
& 'transaction_total_limit
== (if 'block_limit < 'profile_total_limit then
'block_limit
else
'profile_total_limit)
& 'transaction_regular_limit
== (if 'transaction_total_limit < 'profile_regular_limit then
'transaction_total_limit
else
'profile_regular_limit)The protocol parameter tuples admitted by supported forks. Keeping the fields under one constraint preserves their relationships: consumers know that they received one real protocol profile rather than an arbitrary cross-product of individually valid constants.
type protocol_profile_parameters(
'fork : Int,
'target : Int,
'maximum : Int,
'denominator : Int,
'code_limit : Int,
'initcode_limit : Int,
'transaction_total_gas_limit : Int,
'transaction_regular_gas_limit : Int,
'transaction_blob_limit : Int,
'refund_divisor : Int,
) -> Bool =
(
'fork == berlin_fork_value
& 'target == blob_schedule_inactive_count
& 'maximum == blob_schedule_inactive_count
& 'denominator == inactive_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == inactive_initcode_size_limit
& 'transaction_total_gas_limit == ssz_uint_bound
& 'transaction_regular_gas_limit == ssz_uint_bound
& 'transaction_blob_limit == blob_schedule_inactive_count
& 'refund_divisor == pre_london_refund_divisor
)
| (
(
london_fork_value <= 'fork
& 'fork <= paris_fork_value
)
& 'target == blob_schedule_inactive_count
& 'maximum == blob_schedule_inactive_count
& 'denominator == inactive_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == inactive_initcode_size_limit
& 'transaction_total_gas_limit == ssz_uint_bound
& 'transaction_regular_gas_limit == ssz_uint_bound
& 'transaction_blob_limit == blob_schedule_inactive_count
& 'refund_divisor == post_london_refund_divisor
)
| (
'fork == shanghai_fork_value
& 'target == blob_schedule_inactive_count
& 'maximum == blob_schedule_inactive_count
& 'denominator == inactive_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == pre_amsterdam_initcode_size_limit
& 'transaction_total_gas_limit == ssz_uint_bound
& 'transaction_regular_gas_limit == ssz_uint_bound
& 'transaction_blob_limit == blob_schedule_inactive_count
& 'refund_divisor == post_london_refund_divisor
)
| (
'fork == first_blob_fork_value
& 'target == cancun_blob_target_count
& 'maximum == cancun_blob_max_count
& 'denominator == cancun_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == pre_amsterdam_initcode_size_limit
& 'transaction_total_gas_limit == ssz_uint_bound
& 'transaction_regular_gas_limit == ssz_uint_bound
& 'transaction_blob_limit == cancun_blob_max_count
& 'refund_divisor == post_london_refund_divisor
)
| (
'fork == prague_fork_value
& 'target == prague_blob_target_count
& 'maximum == prague_blob_max_count
& 'denominator == prague_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == pre_amsterdam_initcode_size_limit
& 'transaction_total_gas_limit == ssz_uint_bound
& 'transaction_regular_gas_limit == ssz_uint_bound
& 'transaction_blob_limit == prague_blob_max_count
& 'refund_divisor == post_london_refund_divisor
)
| (
'fork == osaka_fork_value
& 'target == prague_blob_target_count
& 'maximum == prague_blob_max_count
& 'denominator == prague_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == pre_amsterdam_initcode_size_limit
& 'transaction_total_gas_limit == eip7825_transaction_gas_limit
& 'transaction_regular_gas_limit == eip7825_transaction_gas_limit
& 'transaction_blob_limit == cancun_blob_max_count
& 'refund_divisor == post_london_refund_divisor
)
| (
'fork == bpo1_fork_value
& 'target == bpo1_blob_target_count
& 'maximum == bpo1_blob_max_count
& 'denominator == bpo1_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == pre_amsterdam_initcode_size_limit
& 'transaction_total_gas_limit == eip7825_transaction_gas_limit
& 'transaction_regular_gas_limit == eip7825_transaction_gas_limit
& 'transaction_blob_limit == cancun_blob_max_count
& 'refund_divisor == post_london_refund_divisor
)
| (
'fork == bpo2_fork_value
& 'target == bpo2_blob_target_count
& 'maximum == bpo2_blob_max_count
& 'denominator == bpo2_blob_fee_update_fraction
& 'code_limit == pre_amsterdam_deployed_code_size_limit
& 'initcode_limit == pre_amsterdam_initcode_size_limit
& 'transaction_total_gas_limit == eip7825_transaction_gas_limit
& 'transaction_regular_gas_limit == eip7825_transaction_gas_limit
& 'transaction_blob_limit == cancun_blob_max_count
& 'refund_divisor == post_london_refund_divisor
)
| (
'fork == amsterdam_fork_value
& 'target == bpo2_blob_target_count
& 'maximum == bpo2_blob_max_count
& 'denominator == bpo2_blob_fee_update_fraction
& 'code_limit == amsterdam_deployed_code_size_limit
& 'initcode_limit == amsterdam_initcode_size_limit
& 'transaction_total_gas_limit == ssz_uint_bound
& 'transaction_regular_gas_limit == eip7825_transaction_gas_limit
…type ExecutionProfileFields¶
The static protocol profile paired with the gas limits derived from it for the executing block, sharing the profile indices so the pair cannot disagree.
struct ExecutionProfileFields(
'fork : Int,
'target : Int,
'maximum : Int,
'denominator : Int,
'code_limit : Int,
'initcode_limit : Int,
'profile_total_limit : Int,
'profile_regular_limit : Int,
'transaction_blob_limit : Int,
'refund_divisor : Int,
'block_limit : Int,
'transaction_total_limit : Int,
'transaction_regular_limit : Int,
), execution_profile_parameters(
'fork,
'target,
'maximum,
'denominator,
'code_limit,
'initcode_limit,
'profile_total_limit,
'profile_regular_limit,
'transaction_blob_limit,
'refund_divisor,
'block_limit,
'transaction_total_limit,
'transaction_regular_limit,
) = {
protocol : ProtocolProfileFields(
'fork,
'target,
'maximum,
'denominator,
'code_limit,
'initcode_limit,
'profile_total_limit,
'profile_regular_limit,
'transaction_blob_limit,
'refund_divisor,
),
gas : GasLimitsFields(
'block_limit,
'profile_total_limit,
'profile_regular_limit,
'transaction_total_limit,
'transaction_regular_limit,
),
}The concrete gas ceilings for the executing block: the header's block limit, the derived per-transaction total and regular limits, and the fixed system-call limits.
struct GasLimitsFields(
'block_limit : Int,
'profile_total_limit : Int,
'profile_regular_limit : Int,
'transaction_total_limit : Int,
'transaction_regular_limit : Int,
), gas_limits_parameters(
'block_limit,
'profile_total_limit,
'profile_regular_limit,
'transaction_total_limit,
'transaction_regular_limit,
) = {
block_limit : int('block_limit),
transaction_total_limit : int('transaction_total_limit),
transaction_regular_limit : int('transaction_regular_limit),
system_regular_limit : int(30000000),
system_state_limit : int(0),
}Execution rules and computation bounds selected together by one schema fork. The singleton indices retain the exact selected parameter tuple.
struct ProtocolProfileFields(
'fork : Int,
'target : Int,
'maximum : Int,
'denominator : Int,
'code_limit : Int,
'initcode_limit : Int,
'transaction_total_gas_limit : Int,
'transaction_regular_gas_limit : Int,
'transaction_blob_limit : Int,
'refund_divisor : Int,
), protocol_profile_parameters(
'fork,
'target,
'maximum,
'denominator,
'code_limit,
'initcode_limit,
'transaction_total_gas_limit,
'transaction_regular_gas_limit,
'transaction_blob_limit,
'refund_divisor,
) = {
fork : int('fork),
blob_schedule : BlobScheduleFields('target, 'maximum, 'denominator),
excess_blob_gas_limit : profile_excess_blob_gas_limit(
'fork,
'target,
'maximum,
'denominator,
),
deployed_code_size_limit : int('code_limit),
initcode_size_limit : int('initcode_limit),
transaction_total_gas_limit : int('transaction_total_gas_limit),
transaction_regular_gas_limit : int('transaction_regular_gas_limit),
transaction_blob_limit : int('transaction_blob_limit),
refund_divisor : int('refund_divisor),
}A static protocol profile and the concrete limits derived from the current
header, indexed together. Sharing the profile indices with GasLimits
prevents independently valid but mutually inconsistent values from being
paired.
type execution_profile_parameters(
'fork : Int,
'target : Int,
'maximum : Int,
'denominator : Int,
'code_limit : Int,
'initcode_limit : Int,
'profile_total_limit : Int,
'profile_regular_limit : Int,
'transaction_blob_limit : Int,
'refund_divisor : Int,
'block_limit : Int,
'transaction_total_limit : Int,
'transaction_regular_limit : Int,
) -> Bool =
protocol_profile_parameters(
'fork,
'target,
'maximum,
'denominator,
'code_limit,
'initcode_limit,
'profile_total_limit,
'profile_regular_limit,
'transaction_blob_limit,
'refund_divisor,
)
& gas_limits_parameters(
'block_limit,
'profile_total_limit,
'profile_regular_limit,
'transaction_total_limit,
'transaction_regular_limit,
)Available gas in a running EVM frame. Every admitted transaction gas
limit originates in the execution payload's SSZ uint64 gas-limit
domain, and child frames can only receive gas from their parent.
type gas = range(0, 2 ^ 64 - 1)type ExecutionProfile¶
An execution profile with its thirteen indices packed existentially.
type ExecutionProfile = {
'fork
'target
'maximum
'denominator
'code_limit
'initcode_limit
'profile_total_limit
'profile_regular_limit
'transaction_blob_limit
'refund_divisor
'block_limit
'transaction_total_limit
'transaction_regular_limit,
execution_profile_parameters(
'fork,
'target,
'maximum,
'denominator,
'code_limit,
'initcode_limit,
'profile_total_limit,
'profile_regular_limit,
'transaction_blob_limit,
'refund_divisor,
'block_limit,
'transaction_total_limit,
'transaction_regular_limit,
).
ExecutionProfileFields(
'fork,
'target,
'maximum,
'denominator,
'code_limit,
'initcode_limit,
'profile_total_limit,
'profile_regular_limit,
'transaction_blob_limit,
'refund_divisor,
'block_limit,
'transaction_total_limit,
'transaction_regular_limit,
)
}The static protocol profile paired with the gas limits derived from it for the executing block, sharing the profile indices so the pair cannot disagree.
struct ExecutionProfileFields(
'fork : Int,
'target : Int,
'maximum : Int,
'denominator : Int,
'code_limit : Int,
'initcode_limit : Int,
'profile_total_limit : Int,
'profile_regular_limit : Int,
'transaction_blob_limit : Int,
'refund_divisor : Int,
'block_limit : Int,
'transaction_total_limit : Int,
'transaction_regular_limit : Int,
), execution_profile_parameters(
'fork,
'target,
'maximum,
'denominator,
'code_limit,
'initcode_limit,
'profile_total_limit,
'profile_regular_limit,
'transaction_blob_limit,
'refund_divisor,
'block_limit,
'transaction_total_limit,
'transaction_regular_limit,
) = {
protocol : ProtocolProfileFields(
'fork,
'target,
'maximum,
'denominator,
'code_limit,
'initcode_limit,
'profile_total_limit,
'profile_regular_limit,
'transaction_blob_limit,
'refund_divisor,
),
gas : GasLimitsFields(
'block_limit,
'profile_total_limit,
'profile_regular_limit,
'transaction_total_limit,
'transaction_regular_limit,
),
}A static protocol profile and the concrete limits derived from the current
header, indexed together. Sharing the profile indices with GasLimits
prevents independently valid but mutually inconsistent values from being
paired.
type execution_profile_parameters(
'fork : Int,
'target : Int,
'maximum : Int,
'denominator : Int,
'code_limit : Int,
'initcode_limit : Int,
'profile_total_limit : Int,
'profile_regular_limit : Int,
'transaction_blob_limit : Int,
'refund_divisor : Int,
'block_limit : Int,
'transaction_total_limit : Int,
'transaction_regular_limit : Int,
) -> Bool =
protocol_profile_parameters(
'fork,
'target,
'maximum,
'denominator,
'code_limit,
'initcode_limit,
'profile_total_limit,
'profile_regular_limit,
'transaction_blob_limit,
'refund_divisor,
)
& gas_limits_parameters(
'block_limit,
'profile_total_limit,
'profile_regular_limit,
'transaction_total_limit,
'transaction_regular_limit,
)function execution_profile_for¶
function execution_profile_for(protocol, block_limit) =
struct { protocol = protocol, gas = gas_limits_for(protocol, block_limit) }function execution_profile_for(protocol, block_limit) =
struct { protocol = protocol, gas = gas_limits_for(protocol, block_limit) }function gas_limits_for(profile, block_limit) = {
let transaction_total_limit =
if block_limit < profile.transaction_total_gas_limit then block_limit else profile.transaction_total_gas_limit;
let transaction_regular_limit =
if transaction_total_limit < profile.transaction_regular_gas_limit
then transaction_total_limit
else profile.transaction_regular_gas_limit;
struct {
block_limit = block_limit,
transaction_total_limit = transaction_total_limit,
transaction_regular_limit = transaction_regular_limit,
system_regular_limit = SYSTEM_CALL_GAS_LIMIT,
system_state_limit = 0,
}
}Available gas in a running EVM frame. Every admitted transaction gas
limit originates in the execution payload's SSZ uint64 gas-limit
domain, and child frames can only receive gas from their parent.
type gas = range(0, 2 ^ 64 - 1)function schema_protocol_profile¶
The schema's stable fork byte selects one complete protocol profile. The branches are the sole table of admitted schema/profile combinations.
function schema_protocol_profile(schema_fork : byte) -> ProtocolProfile =
match schema_fork {
0x0a => {
let profile = struct {
fork = Berlin,
blob_schedule =
blob_schedule(
sizeof(blob_schedule_inactive_count),
sizeof(blob_schedule_inactive_count),
sizeof(inactive_blob_fee_update_fraction),
),
excess_blob_gas_limit =
compute_profile_excess_blob_gas_limit(
Berlin,
sizeof(blob_schedule_inactive_count),
sizeof(blob_schedule_inactive_count),
sizeof(inactive_blob_fee_update_fraction),
),
deployed_code_size_limit = sizeof(pre_amsterdam_deployed_code_size_limit),
initcode_size_limit = sizeof(inactive_initcode_size_limit),
transaction_total_gas_limit = sizeof(ssz_uint_bound),
transaction_regular_gas_limit = sizeof(ssz_uint_bound),
transaction_blob_limit = sizeof(blob_schedule_inactive_count),
refund_divisor = sizeof(pre_london_refund_divisor),
} :
ProtocolProfileFields(
berlin_fork_value,
blob_schedule_inactive_count,
blob_schedule_inactive_count,
inactive_blob_fee_update_fraction,
pre_amsterdam_deployed_code_size_limit,
inactive_initcode_size_limit,
ssz_uint_bound,
ssz_uint_bound,
blob_schedule_inactive_count,
pre_london_refund_divisor,
);
pack_protocol_profile(profile)
},
0x0b => {
let profile = struct {
fork = London,
blob_schedule =
blob_schedule(
sizeof(blob_schedule_inactive_count),
sizeof(blob_schedule_inactive_count),
sizeof(inactive_blob_fee_update_fraction),
),
excess_blob_gas_limit =
compute_profile_excess_blob_gas_limit(
London,
sizeof(blob_schedule_inactive_count),
sizeof(blob_schedule_inactive_count),
sizeof(inactive_blob_fee_update_fraction),
),
deployed_code_size_limit = sizeof(pre_amsterdam_deployed_code_size_limit),
initcode_size_limit = sizeof(inactive_initcode_size_limit),
transaction_total_gas_limit = sizeof(ssz_uint_bound),
transaction_regular_gas_limit = sizeof(ssz_uint_bound),
transaction_blob_limit = sizeof(blob_schedule_inactive_count),
refund_divisor = sizeof(post_london_refund_divisor),
} :
ProtocolProfileFields(
london_fork_value,
blob_schedule_inactive_count,
blob_schedule_inactive_count,
inactive_blob_fee_update_fraction,
pre_amsterdam_deployed_code_size_limit,
inactive_initcode_size_limit,
ssz_uint_bound,
ssz_uint_bound,
blob_schedule_inactive_count,
post_london_refund_divisor,
);
pack_protocol_profile(profile)
},
0x0c => {
let profile = struct {
fork = ArrowGlacier,
blob_schedule =
blob_schedule(
sizeof(blob_schedule_inactive_count),
sizeof(blob_schedule_inactive_count),
sizeof(inactive_blob_fee_update_fraction),
),
excess_blob_gas_limit =
compute_profile_excess_blob_gas_limit(
ArrowGlacier,
sizeof(blob_schedule_inactive_count),
sizeof(blob_schedule_inactive_count),
sizeof(inactive_blob_fee_update_fraction),
),
deployed_code_size_limit = sizeof(pre_amsterdam_deployed_code_size_limit),
initcode_size_limit = sizeof(inactive_initcode_size_limit),
transaction_total_gas_limit = sizeof(ssz_uint_bound),
transaction_regular_gas_limit = sizeof(ssz_uint_bound),
transaction_blob_limit = sizeof(blob_schedule_inactive_count),
refund_divisor = sizeof(post_london_refund_divisor),
} :
ProtocolProfileFields(
arrow_glacier_fork_value,
blob_schedule_inactive_count,
blob_schedule_inactive_count,
inactive_blob_fee_update_fraction,
pre_amsterdam_deployed_code_size_limit,
inactive_initcode_size_limit,
ssz_uint_bound,
ssz_uint_bound,
blob_schedule_inactive_count,
post_london_refund_divisor,
);
pack_protocol_profile(profile)
},
0x0d => {
let profile = struct {
fork = GrayGlacier,
blob_schedule =
blob_schedule(
sizeof(blob_schedule_inactive_count),
sizeof(blob_schedule_inactive_count),
sizeof(inactive_blob_fee_update_fraction),
),
excess_blob_gas_limit =
compute_profile_excess_blob_gas_limit(
GrayGlacier,
sizeof(blob_schedule_inactive_count),
sizeof(blob_schedule_inactive_count),
sizeof(inactive_blob_fee_update_fraction),
),
deployed_code_size_limit = sizeof(pre_amsterdam_deployed_code_size_limit),
initcode_size_limit = sizeof(inactive_initcode_size_limit),
transaction_total_gas_limit = sizeof(ssz_uint_bound),
transaction_regular_gas_limit = sizeof(ssz_uint_bound),
transaction_blob_limit = sizeof(blob_schedule_inactive_count),
refund_divisor = sizeof(post_london_refund_divisor),
} :
ProtocolProfileFields(
gray_glacier_fork_value,
blob_schedule_inactive_count,
blob_schedule_inactive_count,
inactive_blob_fee_update_fraction,
pre_amsterdam_deployed_code_size_limit,
inactive_initcode_size_limit,
ssz_uint_bound,
ssz_uint_bound,
blob_schedule_inactive_count,
post_london_refund_divisor,
);
pack_protocol_profile(profile)
},
0x0e => {
let profile = struct {
fork = Paris,
blob_schedule =
blob_schedule(
sizeof(blob_schedule_inactive_count),
sizeof(blob_schedule_inactive_count),
sizeof(inactive_blob_fee_update_fraction),
),
excess_blob_gas_limit =
compute_profile_excess_blob_gas_limit(
Paris,
sizeof(blob_schedule_inactive_count),
sizeof(blob_schedule_inactive_count),
sizeof(inactive_blob_fee_update_fraction),
),
deployed_code_size_limit = sizeof(pre_amsterdam_deployed_code_size_limit),
initcode_size_limit = sizeof(inactive_initcode_size_limit),
transaction_total_gas_limit = sizeof(ssz_uint_bound),
transaction_regular_gas_limit = sizeof(ssz_uint_bound),
transaction_blob_limit = sizeof(blob_schedule_inactive_count),
refund_divisor = sizeof(post_london_refund_divisor),
} :
ProtocolProfileFields(
paris_fork_value,
blob_schedule_inactive_count,
blob_schedule_inactive_count,
inactive_blob_fee_update_fraction,
pre_amsterdam_deployed_code_size_limit,
inactive_initcode_size_limit,
ssz_uint_bound,
ssz_uint_bound,
blob_schedule_inactive_count,
post_london_refund_divisor,
);
pack_protocol_profile(profile)
},
0x0f => {
let profile = struct {
fork = Shanghai,
blob_schedule =
blob_schedule(
sizeof(blob_schedule_inactive_count),
sizeof(blob_schedule_inactive_count),
sizeof(inactive_blob_fee_update_fraction),
),
excess_blob_gas_limit =
compute_profile_excess_blob_gas_limit(
Shanghai,
sizeof(blob_schedule_inactive_count),
sizeof(blob_schedule_inactive_count),
sizeof(inactive_blob_fee_update_fraction),
),
deployed_code_size_limit = sizeof(pre_amsterdam_deployed_code_size_limit),
initcode_size_limit = sizeof(pre_amsterdam_initcode_size_limit),
transaction_total_gas_limit = sizeof(ssz_uint_bound),
transaction_regular_gas_limit = sizeof(ssz_uint_bound),
transaction_blob_limit = sizeof(blob_schedule_inactive_count),
refund_divisor = sizeof(post_london_refund_divisor),
} :
ProtocolProfileFields(
shanghai_fork_value,
blob_schedule_inactive_count,
blob_schedule_inactive_count,
inactive_blob_fee_update_fraction,
pre_amsterdam_deployed_code_size_limit,
pre_amsterdam_initcode_size_limit,
ssz_uint_bound,
ssz_uint_bound,
blob_schedule_inactive_count,
post_london_refund_divisor,
);
pack_protocol_profile(profile)
},
0x10 => {
let profile = struct {
fork = Cancun,
blob_schedule =
blob_schedule(
sizeof(cancun_blob_target_count),
sizeof(cancun_blob_max_count),
sizeof(cancun_blob_fee_update_fraction),
),
excess_blob_gas_limit =
compute_profile_excess_blob_gas_limit(
Cancun,
sizeof(cancun_blob_target_count),
sizeof(cancun_blob_max_count),
sizeof(cancun_blob_fee_update_fraction),
),
deployed_code_size_limit = sizeof(pre_amsterdam_deployed_code_size_limit),
initcode_size_limit = sizeof(pre_amsterdam_initcode_size_limit),
transaction_total_gas_limit = sizeof(ssz_uint_bound),
transaction_regular_gas_limit = sizeof(ssz_uint_bound),
transaction_blob_limit = sizeof(cancun_blob_max_count),
refund_divisor = sizeof(post_london_refund_divisor),
} :
ProtocolProfileFields(
first_blob_fork_value,
cancun_blob_target_count,
cancun_blob_max_count,
cancun_blob_fee_update_fraction,
pre_amsterdam_deployed_code_size_limit,
pre_amsterdam_initcode_size_limit,
ssz_uint_bound,
ssz_uint_bound,
cancun_blob_max_count,
post_london_refund_divisor,
);
pack_protocol_profile(profile)
},
0x11 => {
let profile = struct {
fork = Prague,
blob_schedule =
blob_schedule(
sizeof(prague_blob_target_count),
sizeof(prague_blob_max_count),
sizeof(prague_blob_fee_update_fraction),
),
excess_blob_gas_limit =
compute_profile_excess_blob_gas_limit(
Prague,
sizeof(prague_blob_target_count),
sizeof(prague_blob_max_count),
sizeof(prague_blob_fee_update_fraction),
),
deployed_code_size_limit = sizeof(pre_amsterdam_deployed_code_size_limit),
initcode_size_limit = sizeof(pre_amsterdam_initcode_size_limit),
transaction_total_gas_limit = sizeof(ssz_uint_bound),
transaction_regular_gas_limit = sizeof(ssz_uint_bound),
transaction_blob_limit = sizeof(prague_blob_max_count),
refund_divisor = sizeof(post_london_refund_divisor),
} :
ProtocolProfileFields(
prague_fork_value,
prague_blob_target_count,
prague_blob_max_count,
prague_blob_fee_update_fraction,
pre_amsterdam_deployed_code_size_limit,
pre_amsterdam_initcode_size_limit,
ssz_uint_bound,
ssz_uint_bound,
prague_blob_max_count,
post_london_refund_divisor,
);
pack_protocol_profile(profile)
},
0x12 => {
let profile = struct {
fork = Osaka,
blob_schedule =
blob_schedule(
sizeof(prague_blob_target_count),
sizeof(prague_blob_max_count),
sizeof(prague_blob_fee_update_fraction),
),
excess_blob_gas_limit =
compute_profile_excess_blob_gas_limit(
Osaka,
sizeof(prague_blob_target_count),
sizeof(prague_blob_max_count),
sizeof(prague_blob_fee_update_fraction),
),
deployed_code_size_limit = sizeof(pre_amsterdam_deployed_code_size_limit),
initcode_size_limit = sizeof(pre_amsterdam_initcode_size_limit),
transaction_total_gas_limit = sizeof(eip7825_transaction_gas_limit),
transaction_regular_gas_limit = sizeof(eip7825_transaction_gas_limit),
transaction_blob_limit = sizeof(cancun_blob_max_count),
refund_divisor = sizeof(post_london_refund_divisor),
} :
ProtocolProfileFields(
osaka_fork_value,
prague_blob_target_count,
prague_blob_max_count,
prague_blob_fee_update_fraction,
pre_amsterdam_deployed_code_size_limit,
pre_amsterdam_initcode_size_limit,
eip7825_transaction_gas_limit,
eip7825_transaction_gas_limit,
cancun_blob_max_count,
post_london_refund_divisor,
);
pack_protocol_profile(profile)
},
0x13 => {
let profile = struct {
fork = BPO1,
blob_schedule =
blob_schedule(
sizeof(bpo1_blob_target_count),
sizeof(bpo1_blob_max_count),
sizeof(bpo1_blob_fee_update_fraction),
),
excess_blob_gas_limit =
compute_profile_excess_blob_gas_limit(
BPO1,
sizeof(bpo1_blob_target_count),
sizeof(bpo1_blob_max_count),
sizeof(bpo1_blob_fee_update_fraction),
),
deployed_code_size_limit = sizeof(pre_amsterdam_deployed_code_size_limit),
initcode_size_limit = sizeof(pre_amsterdam_initcode_size_limit),
transaction_total_gas_limit = sizeof(eip7825_transaction_gas_limit),
transaction_regular_gas_limit = sizeof(eip7825_transaction_gas_limit),
transaction_blob_limit = sizeof(cancun_blob_max_count),
refund_divisor = sizeof(post_london_refund_divisor),
} :
ProtocolProfileFields(
bpo1_fork_value,
bpo1_blob_target_count,
bpo1_blob_max_count,
bpo1_blob_fee_update_fraction,
pre_amsterdam_deployed_code_size_limit,
pre_amsterdam_initcode_size_limit,
eip7825_transaction_gas_limit,
eip7825_transaction_gas_limit,
cancun_blob_max_count,
post_london_refund_divisor,
);
pack_protocol_profile(profile)
},
0x14 => {
let profile = struct {
fork = BPO2,
blob_schedule =
blob_schedule(
sizeof(bpo2_blob_target_count),
sizeof(bpo2_blob_max_count),
sizeof(bpo2_blob_fee_update_fraction),
),
excess_blob_gas_limit =
compute_profile_excess_blob_gas_limit(
BPO2,
sizeof(bpo2_blob_target_count),
sizeof(bpo2_blob_max_count),
sizeof(bpo2_blob_fee_update_fraction),
),
deployed_code_size_limit = sizeof(pre_amsterdam_deployed_code_size_limit),
initcode_size_limit = sizeof(pre_amsterdam_initcode_size_limit),
transaction_total_gas_limit = sizeof(eip7825_transaction_gas_limit),
transaction_regular_gas_limit = sizeof(eip7825_transaction_gas_limit),
transaction_blob_limit = sizeof(cancun_blob_max_count),
refund_divisor = sizeof(post_london_refund_divisor),
} :
ProtocolProfileFields(
bpo2_fork_value,
bpo2_blob_target_count,
bpo2_blob_max_count,
bpo2_blob_fee_update_fraction,
pre_amsterdam_deployed_code_size_limit,
pre_amsterdam_initcode_size_limit,
eip7825_transaction_gas_limit,
eip7825_transaction_gas_limit,
cancun_blob_max_count,
post_london_refund_divisor,
);
pack_protocol_profile(profile)
},
_ => {
let profile = struct {
fork = Amsterdam,
blob_schedule =
blob_schedule(
sizeof(bpo2_blob_target_count),
sizeof(bpo2_blob_max_count),
sizeof(bpo2_blob_fee_update_fraction),
),
excess_blob_gas_limit =
compute_profile_excess_blob_gas_limit(
Amsterdam,
sizeof(bpo2_blob_target_count),
sizeof(bpo2_blob_max_count),
sizeof(bpo2_blob_fee_update_fraction),
),
deployed_code_size_limit = sizeof(amsterdam_deployed_code_size_limit),
initcode_size_limit = sizeof(amsterdam_initcode_size_limit),
transaction_total_gas_limit = sizeof(ssz_uint_bound),
transaction_regular_gas_limit = sizeof(eip7825_transaction_gas_limit),
transaction_blob_limit = sizeof(cancun_blob_max_count),
refund_divisor = sizeof(post_london_refund_divisor),
} :
ProtocolProfileFields(
amsterdam_fork_value,
bpo2_blob_target_count,
bpo2_blob_max_count,
bpo2_blob_fee_update_fraction,
amsterdam_deployed_code_size_limit,
amsterdam_initcode_size_limit,
ssz_uint_bound,
eip7825_transaction_gas_limit,
cancun_blob_max_count,
post_london_refund_divisor,
);
pack_protocol_profile(profile)
},
}function blob_schedule(target, maximum, denominator) =
struct { target = target, max = maximum, base_fee_update_fraction = denominator }function compute_profile_excess_blob_gas_limit(fork, target, maximum, denominator) =
if fork < Cancun then {
0
} else {
sizeof(blob_fee_word_exponent_limit) * denominator + (maximum - target) * sizeof(gas_per_blob_value)
}function pack_protocol_profile(profile) = profileEIP-7954 code/initcode size bump (65536/131072).
let Amsterdam : int(amsterdam_fork_value) = sizeof(amsterdam_fork_value)Difficulty-bomb-only schema fork; execution rules remain London.
let ArrowGlacier : int(arrow_glacier_fork_value) = sizeof(arrow_glacier_fork_value)First blob-parameter-only fork; execution rules remain Osaka.
let BPO1 : int(bpo1_fork_value) = sizeof(bpo1_fork_value)Second blob-parameter-only fork; execution rules remain Osaka.
let BPO2 : int(bpo2_fork_value) = sizeof(bpo2_fork_value)EIP-2929/2930 access lists and warm/cold access costs.
let Berlin : int(berlin_fork_value) = sizeof(berlin_fork_value)EIP-1153/4844; precompiles 0x01-0x0a.
let Cancun : int(first_blob_fork_value) = sizeof(first_blob_fork_value)Difficulty-bomb-only schema fork; execution rules remain London.
let GrayGlacier : int(gray_glacier_fork_value) = sizeof(gray_glacier_fork_value)EIP-1559 fee market and EIP-3529 refund reduction.
let London : int(london_fork_value) = sizeof(london_fork_value)EIP-7883 modexp gas, EIP-7825 cap; precompile 0x100.
let Osaka : int(osaka_fork_value) = sizeof(osaka_fork_value)EIP-4399 PREVRANDAO replaces DIFFICULTY.
let Paris : int(paris_fork_value) = sizeof(paris_fork_value)EIP-7623 calldata floor; BLS precompiles 0x0b-0x11.
let Prague : int(prague_fork_value) = sizeof(prague_fork_value)EIP-3651 warm coinbase, EIP-3855 PUSH0, EIP-3860 initcode.
let Shanghai : int(shanghai_fork_value) = sizeof(shanghai_fork_value)A protocol profile with its parameter tuple packed existentially; unpacking recovers the admitted combination's equations.
type ProtocolProfile = {
'fork
'target
'maximum
'denominator
'code_limit
'initcode_limit
'transaction_total_gas_limit
'transaction_regular_gas_limit
'transaction_blob_limit
'refund_divisor,
protocol_profile_parameters(
'fork,
'target,
'maximum,
'denominator,
'code_limit,
'initcode_limit,
'transaction_total_gas_limit,
'transaction_regular_gas_limit,
'transaction_blob_limit,
'refund_divisor,
).
ProtocolProfileFields(
'fork,
'target,
'maximum,
'denominator,
'code_limit,
'initcode_limit,
'transaction_total_gas_limit,
'transaction_regular_gas_limit,
'transaction_blob_limit,
'refund_divisor,
)
}Execution rules and computation bounds selected together by one schema fork. The singleton indices retain the exact selected parameter tuple.
struct ProtocolProfileFields(
'fork : Int,
'target : Int,
'maximum : Int,
'denominator : Int,
'code_limit : Int,
'initcode_limit : Int,
'transaction_total_gas_limit : Int,
'transaction_regular_gas_limit : Int,
'transaction_blob_limit : Int,
'refund_divisor : Int,
), protocol_profile_parameters(
'fork,
'target,
'maximum,
'denominator,
'code_limit,
'initcode_limit,
'transaction_total_gas_limit,
'transaction_regular_gas_limit,
'transaction_blob_limit,
'refund_divisor,
) = {
fork : int('fork),
blob_schedule : BlobScheduleFields('target, 'maximum, 'denominator),
excess_blob_gas_limit : profile_excess_blob_gas_limit(
'fork,
'target,
'maximum,
'denominator,
),
deployed_code_size_limit : int('code_limit),
initcode_size_limit : int('initcode_limit),
transaction_total_gas_limit : int('transaction_total_gas_limit),
transaction_regular_gas_limit : int('transaction_regular_gas_limit),
transaction_blob_limit : int('transaction_blob_limit),
refund_divisor : int('refund_divisor),
}Amsterdam's raised deployed-code size limit of 65,536 bytes.
type amsterdam_deployed_code_size_limit : Int = 65536Amsterdam's position in the activation order.
type amsterdam_fork_value : Int = 16Amsterdam's raised initcode size limit of 131,072 bytes.
type amsterdam_initcode_size_limit : Int = 131072ArrowGlacier's position in the activation order.
type arrow_glacier_fork_value : Int = 7Berlin's position in the activation order.
type berlin_fork_value : Int = 5Named blob-schedule constants retained by the profile domains below.
type blob_schedule_inactive_count : Int = 0The BPO1 blob-fee update fraction.
type bpo1_blob_fee_update_fraction : Int = 8346193The BPO1 per-block blob maximum of 15.
type bpo1_blob_max_count : Int = 15The BPO1 per-block blob target of 10.
type bpo1_blob_target_count : Int = 10BPO1's position in the activation order.
type bpo1_fork_value : Int = 14The BPO2 blob-fee update fraction (EIP-8135).
type bpo2_blob_fee_update_fraction : Int = 11684671The BPO2 per-block blob maximum of 21.
type bpo2_blob_max_count : Int = 21The BPO2 per-block blob target of 14.
type bpo2_blob_target_count : Int = 14BPO2's position in the activation order.
type bpo2_fork_value : Int = 15An 8-bit byte.
type byte = bits(8)Cancun's BLOB_BASE_FEE_UPDATE_FRACTION (EIP-4844).
type cancun_blob_fee_update_fraction : Int = 3338477Cancun's per-block blob maximum of 6 (EIP-4844).
type cancun_blob_max_count : Int = 6Cancun's per-block blob target of 3 (EIP-4844).
type cancun_blob_target_count : Int = 3The EIP-7825 per-transaction gas cap of 2^24.
type eip7825_transaction_gas_limit : Int = 2 ^ 24First fork at which blob gas is active. Kept as a type-level singleton so
profile equations and the runtime Cancun value share one boundary.
type first_blob_fork_value : Int = 11GrayGlacier's position in the activation order.
type gray_glacier_fork_value : Int = 8Named EIP-4844/BPO fee-update fractions.
type inactive_blob_fee_update_fraction : Int = 1The zero initcode limit for profiles before EIP-3860 activates.
type inactive_initcode_size_limit : Int = 0London's position in the activation order.
type london_fork_value : Int = 6Osaka's position in the activation order.
type osaka_fork_value : Int = 13Paris's position in the activation order.
type paris_fork_value : Int = 9The London refund divisor: EIP-3529 caps refunds at gas_used / 5.
type post_london_refund_divisor : Int = 5Prague's BLOB_BASE_FEE_UPDATE_FRACTION (EIP-7691).
type prague_blob_fee_update_fraction : Int = 5007716Prague's per-block blob maximum of 9 (EIP-7691).
type prague_blob_max_count : Int = 9Prague's per-block blob target of 6 (EIP-7691).
type prague_blob_target_count : Int = 6Prague's position in the activation order.
type prague_fork_value : Int = 12Fork-selected limits retained in the validated protocol profile. A fork
without a stricter transaction-gas cap admits the complete SSZ uint64
block-gas domain; the concrete header limit is applied separately.
type pre_amsterdam_deployed_code_size_limit : Int = 24576The EIP-3860 initcode size limit of 49,152 bytes.
type pre_amsterdam_initcode_size_limit : Int = 49152The pre-London refund divisor: refunds are capped at gas_used / 2.
type pre_london_refund_divisor : Int = 2Shanghai's position in the activation order.
type shanghai_fork_value : Int = 10Largest value represented by an SSZ uint64. This is a wire-schema
constraint, sourced from the consensus ExecutionPayload container and
the Amsterdam SszExecutionPayload, rather than an implementation word
size.
type ssz_uint_bound : Int = 2 ^ 64 - 1A fork-selected per-transaction blob limit drawn from the supported schedules; zero for profiles before blob transactions activate.
type transaction_blob_limit = {
'value,
transaction_blob_limit_value('value).
int('value)
}function schema_protocol_profile_forwards_matches¶
Whether a schema fork byte has a protocol-profile branch.
function schema_protocol_profile_forwards_matches(schema_fork : byte) -> bool =
(schema_fork == 0x0a)
| (schema_fork == 0x0b)
| (schema_fork == 0x0c)
| (schema_fork == 0x0d)
| (schema_fork == 0x0e)
| (schema_fork == 0x0f)
| (schema_fork == 0x10)
| (schema_fork == 0x11)
| (schema_fork == 0x12)
| (schema_fork == 0x13)
| (schema_fork == 0x14)
| (schema_fork == 0x15)An 8-bit byte.
type byte = bits(8)let DEFAULT_PROTOCOL_PROFILE¶
The Amsterdam mapping entry initializes the kernel before input decoding.
let DEFAULT_PROTOCOL_PROFILE : ProtocolProfile = schema_protocol_profile(0x15)The schema's stable fork byte selects one complete protocol profile. The branches are the sole table of admitted schema/profile combinations.
function schema_protocol_profile(schema_fork : byte) -> ProtocolProfile =
match schema_fork {
0x0a => {
let profile = struct {
fork = Berlin,
blob_schedule =
blob_schedule(
sizeof(blob_schedule_inactive_count),
sizeof(blob_schedule_inactive_count),
sizeof(inactive_blob_fee_update_fraction),
),
excess_blob_gas_limit =
compute_profile_excess_blob_gas_limit(
Berlin,
sizeof(blob_schedule_inactive_count),
sizeof(blob_schedule_inactive_count),
sizeof(inactive_blob_fee_update_fraction),
),
deployed_code_size_limit = sizeof(pre_amsterdam_deployed_code_size_limit),
initcode_size_limit = sizeof(inactive_initcode_size_limit),
transaction_total_gas_limit = sizeof(ssz_uint_bound),
transaction_regular_gas_limit = sizeof(ssz_uint_bound),
transaction_blob_limit = sizeof(blob_schedule_inactive_count),
refund_divisor = sizeof(pre_london_refund_divisor),
} :
ProtocolProfileFields(
berlin_fork_value,
blob_schedule_inactive_count,
blob_schedule_inactive_count,
inactive_blob_fee_update_fraction,
pre_amsterdam_deployed_code_size_limit,
inactive_initcode_size_limit,
ssz_uint_bound,
ssz_uint_bound,
blob_schedule_inactive_count,
pre_london_refund_divisor,
);
pack_protocol_profile(profile)
},
0x0b => {
let profile = struct {
fork = London,
blob_schedule =
blob_schedule(
sizeof(blob_schedule_inactive_count),
sizeof(blob_schedule_inactive_count),
sizeof(inactive_blob_fee_update_fraction),
),
excess_blob_gas_limit =
compute_profile_excess_blob_gas_limit(
London,
sizeof(blob_schedule_inactive_count),
sizeof(blob_schedule_inactive_count),
sizeof(inactive_blob_fee_update_fraction),
),
deployed_code_size_limit = sizeof(pre_amsterdam_deployed_code_size_limit),
initcode_size_limit = sizeof(inactive_initcode_size_limit),
transaction_total_gas_limit = sizeof(ssz_uint_bound),
transaction_regular_gas_limit = sizeof(ssz_uint_bound),
transaction_blob_limit = sizeof(blob_schedule_inactive_count),
refund_divisor = sizeof(post_london_refund_divisor),
} :
ProtocolProfileFields(
london_fork_value,
blob_schedule_inactive_count,
blob_schedule_inactive_count,
inactive_blob_fee_update_fraction,
pre_amsterdam_deployed_code_size_limit,
inactive_initcode_size_limit,
ssz_uint_bound,
ssz_uint_bound,
blob_schedule_inactive_count,
post_london_refund_divisor,
);
pack_protocol_profile(profile)
},
0x0c => {
let profile = struct {
fork = ArrowGlacier,
blob_schedule =
blob_schedule(
sizeof(blob_schedule_inactive_count),
sizeof(blob_schedule_inactive_count),
sizeof(inactive_blob_fee_update_fraction),
),
excess_blob_gas_limit =
compute_profile_excess_blob_gas_limit(
ArrowGlacier,
sizeof(blob_schedule_inactive_count),
sizeof(blob_schedule_inactive_count),
sizeof(inactive_blob_fee_update_fraction),
),
deployed_code_size_limit = sizeof(pre_amsterdam_deployed_code_size_limit),
initcode_size_limit = sizeof(inactive_initcode_size_limit),
transaction_total_gas_limit = sizeof(ssz_uint_bound),
transaction_regular_gas_limit = sizeof(ssz_uint_bound),
transaction_blob_limit = sizeof(blob_schedule_inactive_count),
refund_divisor = sizeof(post_london_refund_divisor),
} :
ProtocolProfileFields(
arrow_glacier_fork_value,
blob_schedule_inactive_count,
blob_schedule_inactive_count,
inactive_blob_fee_update_fraction,
pre_amsterdam_deployed_code_size_limit,
inactive_initcode_size_limit,
ssz_uint_bound,
ssz_uint_bound,
blob_schedule_inactive_count,
post_london_refund_divisor,
);
pack_protocol_profile(profile)
},
0x0d => {
let profile = struct {
fork = GrayGlacier,
blob_schedule =
blob_schedule(
sizeof(blob_schedule_inactive_count),
sizeof(blob_schedule_inactive_count),
…A protocol profile with its parameter tuple packed existentially; unpacking recovers the admitted combination's equations.
type ProtocolProfile = {
'fork
'target
'maximum
'denominator
'code_limit
'initcode_limit
'transaction_total_gas_limit
'transaction_regular_gas_limit
'transaction_blob_limit
'refund_divisor,
protocol_profile_parameters(
'fork,
'target,
'maximum,
'denominator,
'code_limit,
'initcode_limit,
'transaction_total_gas_limit,
'transaction_regular_gas_limit,
'transaction_blob_limit,
'refund_divisor,
).
ProtocolProfileFields(
'fork,
'target,
'maximum,
'denominator,
'code_limit,
'initcode_limit,
'transaction_total_gas_limit,
'transaction_regular_gas_limit,
'transaction_blob_limit,
'refund_divisor,
)
}let DEFAULT_EXECUTION_PROFILE¶
let DEFAULT_EXECUTION_PROFILE : ExecutionProfile = execution_profile_for(DEFAULT_PROTOCOL_PROFILE, 0)function execution_profile_for(protocol, block_limit) =
struct { protocol = protocol, gas = gas_limits_for(protocol, block_limit) }The Amsterdam mapping entry initializes the kernel before input decoding.
let DEFAULT_PROTOCOL_PROFILE : ProtocolProfile = schema_protocol_profile(0x15)An execution profile with its thirteen indices packed existentially.
type ExecutionProfile = {
'fork
'target
'maximum
'denominator
'code_limit
'initcode_limit
'profile_total_limit
'profile_regular_limit
'transaction_blob_limit
'refund_divisor
'block_limit
'transaction_total_limit
'transaction_regular_limit,
execution_profile_parameters(
'fork,
'target,
'maximum,
'denominator,
'code_limit,
'initcode_limit,
'profile_total_limit,
'profile_regular_limit,
'transaction_blob_limit,
'refund_divisor,
'block_limit,
'transaction_total_limit,
'transaction_regular_limit,
).
ExecutionProfileFields(
'fork,
'target,
'maximum,
'denominator,
'code_limit,
'initcode_limit,
'profile_total_limit,
'profile_regular_limit,
'transaction_blob_limit,
'refund_divisor,
'block_limit,
'transaction_total_limit,
'transaction_regular_limit,
)
}type ChainConfig¶
The decoded chain configuration for the executing payload.
struct ChainConfig = {
chain_id : chain_identifier,
}A chain identifier. Typed-transaction chain identifiers and the stateless chain configuration are decoded as unsigned 64-bit integers.
type chain_identifier = range(0, chain_identifier_bound)