diff --git a/src/lean_spec/subspecs/chain/__init__.py b/src/lean_spec/subspecs/chain/__init__.py new file mode 100644 index 00000000..9ffe8101 --- /dev/null +++ b/src/lean_spec/subspecs/chain/__init__.py @@ -0,0 +1,7 @@ +"""Specifications for chain and consensus parameters.""" + +from .config import DEVNET_CONFIG + +__all__ = [ + "DEVNET_CONFIG", +] diff --git a/src/lean_spec/subspecs/chain/config.py b/src/lean_spec/subspecs/chain/config.py new file mode 100644 index 00000000..7bb5bfbe --- /dev/null +++ b/src/lean_spec/subspecs/chain/config.py @@ -0,0 +1,86 @@ +""" +Chain and Consensus Configuration Specification + +This file defines the core consensus parameters and chain presets for the +Lean Consensus Experimental Chain. +""" + +from pydantic import BaseModel, ConfigDict +from typing_extensions import Final + +from lean_spec.subspecs.types import BasisPoint, uint64 + +# --- Time Parameters --- + +# The fixed duration of a single slot in milliseconds. +SLOT_DURATION_MS: Final = 4000 + +# The deadline within a slot (in basis points) for a proposer to publish a +# block. +# +# Honest validators may re-org blocks published after this cutoff. +# +# (2500 bps = 25% of slot duration). +PROPOSER_REORG_CUTOFF_BPS: Final = 2500 + +# The deadline within a slot (in basis points) by which validators must +# submit their votes. +# +# (5000 bps = 50% of slot duration). +VOTE_DUE_BPS: Final = 5000 + +# The deadline within a slot (in basis points) for achieving a fast +# confirmation. +# +# (7500 bps = 75% of slot duration). +FAST_CONFIRM_DUE_BPS: Final = 7500 + +# The cutoff within a slot (in basis points) after which the current view is +# considered 'frozen', preventing further changes. +# +# (7500 bps = 75% of slot duration). +VIEW_FREEZE_CUTOFF_BPS: Final = 7500 + +# --- State List Length Presets --- + +# The maximum number of historical block roots to store in the state. +# +# With a 4-second slot, this corresponds to a history +# of approximately 12.1 days. +HISTORICAL_ROOTS_LIMIT: Final = 2**18 + +# The maximum number of validators that can be in the registry. +VALIDATOR_REGISTRY_LIMIT: Final = 2**12 + + +class _ChainConfig(BaseModel): + """ + A model holding the canonical, immutable configuration constants + for the chain. + """ + + # Configuration to make the model immutable. + model_config = ConfigDict(frozen=True, extra="forbid") + + # Time Parameters + slot_duration_ms: uint64 + proposer_reorg_cutoff_bps: BasisPoint + vote_due_bps: BasisPoint + fast_confirm_due_bps: BasisPoint + view_freeze_cutoff_bps: BasisPoint + + # State List Length Presets + historical_roots_limit: uint64 + validator_registry_limit: uint64 + + +# The Devnet Chain Configuration. +DEVNET_CONFIG: Final = _ChainConfig( + slot_duration_ms=SLOT_DURATION_MS, + proposer_reorg_cutoff_bps=PROPOSER_REORG_CUTOFF_BPS, + vote_due_bps=VOTE_DUE_BPS, + fast_confirm_due_bps=FAST_CONFIRM_DUE_BPS, + view_freeze_cutoff_bps=VIEW_FREEZE_CUTOFF_BPS, + historical_roots_limit=HISTORICAL_ROOTS_LIMIT, + validator_registry_limit=VALIDATOR_REGISTRY_LIMIT, +) diff --git a/src/lean_spec/subspecs/types/__init__.py b/src/lean_spec/subspecs/types/__init__.py new file mode 100644 index 00000000..57173887 --- /dev/null +++ b/src/lean_spec/subspecs/types/__init__.py @@ -0,0 +1,9 @@ +"""Reusable type definitions for the Lean Ethereum specification.""" + +from .basispt import BasisPoint +from .uint64 import uint64 + +__all__ = [ + "uint64", + "BasisPoint", +] diff --git a/src/lean_spec/subspecs/types/basispt.py b/src/lean_spec/subspecs/types/basispt.py new file mode 100644 index 00000000..821a4f87 --- /dev/null +++ b/src/lean_spec/subspecs/types/basispt.py @@ -0,0 +1,14 @@ +"""Basis Point Type Specification.""" + +from pydantic import Field +from typing_extensions import Annotated + +from ..types import uint64 + +# A type alias for basis points +# +# A basis point (bps) is 1/100th of a percent. 100% = 10,000 bps. +BasisPoint = Annotated[ + uint64, + Field(le=10000, description="A value in basis points (1/10000)."), +] diff --git a/src/lean_spec/subspecs/types/uint64.py b/src/lean_spec/subspecs/types/uint64.py new file mode 100644 index 00000000..9a7abb31 --- /dev/null +++ b/src/lean_spec/subspecs/types/uint64.py @@ -0,0 +1,10 @@ +"""Unsigned 64-bit Integer Type Specification.""" + +from pydantic import Field +from typing_extensions import Annotated + +# The maximum value for an unsigned 64-bit integer (2**64). +UINT64_MAX = 2**64 + +# A type alias to represent a uint64. +uint64 = Annotated[int, Field(ge=0, lt=UINT64_MAX)]