Skip to content

Commit 0baaa1e

Browse files
authored
Merge pull request leanEthereum#18 from tcoratger/containers
containers: add subspec for containers
2 parents 9d8bfe8 + 3daa062 commit 0baaa1e

13 files changed

Lines changed: 272 additions & 16 deletions

File tree

src/lean_spec/subspecs/chain/config.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from pydantic import BaseModel, ConfigDict
99
from typing_extensions import Final
1010

11-
from ..types import BasisPoint, uint64
11+
from lean_spec.types import BasisPoint, Uint64
1212

1313
# --- Time Parameters ---
1414

@@ -73,15 +73,15 @@ class _ChainConfig(BaseModel):
7373
model_config = ConfigDict(frozen=True, extra="forbid")
7474

7575
# Time Parameters
76-
slot_duration_ms: uint64
76+
slot_duration_ms: Uint64
7777
proposer_reorg_cutoff_bps: BasisPoint
7878
vote_due_bps: BasisPoint
7979
fast_confirm_due_bps: BasisPoint
8080
view_freeze_cutoff_bps: BasisPoint
8181

8282
# State List Length Presets
83-
historical_roots_limit: uint64
84-
validator_registry_limit: uint64
83+
historical_roots_limit: Uint64
84+
validator_registry_limit: Uint64
8585

8686

8787
# The Devnet Chain Configuration.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
"""The container types for the Lean consensus specification."""
2+
3+
from .block import Block, BlockBody, BlockHeader, SignedBlock
4+
from .checkpoint import Checkpoint
5+
from .config import Config
6+
from .state import State
7+
from .vote import SignedVote, Vote
8+
9+
__all__ = [
10+
"Block",
11+
"BlockBody",
12+
"BlockHeader",
13+
"Checkpoint",
14+
"Config",
15+
"SignedBlock",
16+
"SignedVote",
17+
"State",
18+
"Vote",
19+
]
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
"""Block Containers."""
2+
3+
from pydantic import Field
4+
from typing_extensions import Annotated
5+
6+
from lean_spec.types import Bytes32, StrictBaseModel, Uint64
7+
8+
from ..chain import config
9+
from .vote import Vote
10+
11+
12+
class BlockBody(StrictBaseModel):
13+
"""The body of a block, containing payload data."""
14+
15+
votes: Annotated[
16+
list[Vote],
17+
Field(max_length=config.VALIDATOR_REGISTRY_LIMIT),
18+
]
19+
"""
20+
A list of votes included in the block.
21+
22+
Note: This will eventually be replaced by aggregated attestations.
23+
"""
24+
25+
26+
class BlockHeader(StrictBaseModel):
27+
"""The header of a block, containing metadata."""
28+
29+
slot: Uint64
30+
"""The slot in which the block was proposed."""
31+
32+
proposer_index: Uint64
33+
"""The index of the validator that proposed the block."""
34+
35+
parent_root: Bytes32
36+
"""The root of the parent block."""
37+
38+
state_root: Bytes32
39+
"""The root of the state after processing the block."""
40+
41+
body_root: Bytes32
42+
"""The root of the block's body."""
43+
44+
45+
class Block(StrictBaseModel):
46+
"""Represents a single block in the chain."""
47+
48+
slot: Uint64
49+
"""The slot in which the block was proposed."""
50+
51+
proposer_index: Uint64
52+
"""The index of the validator that proposed the block."""
53+
54+
parent_root: Bytes32
55+
"""The root of the parent block."""
56+
57+
state_root: Bytes32
58+
"""The root of the state after applying transactions in this block."""
59+
60+
body: BlockBody
61+
"""The block's payload."""
62+
63+
64+
class SignedBlock(StrictBaseModel):
65+
"""A container for a block and the proposer's signature."""
66+
67+
message: Block
68+
"""The block data that was signed."""
69+
70+
signature: Bytes32
71+
"""
72+
The proposer's signature of the block message.
73+
74+
Note: Bytes32 is a placeholder; the actual signature is much larger.
75+
"""
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
"""Checkpoint Container."""
2+
3+
from lean_spec.types import Bytes32, StrictBaseModel, Uint64
4+
5+
6+
class Checkpoint(StrictBaseModel):
7+
"""Represents a checkpoint in the chain's history."""
8+
9+
root: Bytes32
10+
"""The root hash of the checkpoint's block."""
11+
12+
slot: Uint64
13+
"""The slot number of the checkpoint's block."""
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
"""Consensus Configuration Container."""
2+
3+
from lean_spec.types import StrictBaseModel, Uint64
4+
5+
6+
class Config(StrictBaseModel):
7+
"""
8+
Holds temporary configuration properties for simplified consensus.
9+
10+
Note: These fields support a simplified round-robin block production
11+
in the absence of more complex mechanisms like RANDAO or deposits.
12+
"""
13+
14+
num_validators: Uint64
15+
"""The total number of validators in the network."""
16+
17+
genesis_time: Uint64
18+
"""The timestamp of the genesis block."""
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
"""State Container."""
2+
3+
from pydantic import Field
4+
from typing_extensions import Annotated
5+
6+
from lean_spec.subspecs.chain import DEVNET_CONFIG
7+
from lean_spec.types import Bytes32, StrictBaseModel, Uint64
8+
9+
from .block import BlockHeader
10+
from .checkpoint import Checkpoint
11+
from .config import Config
12+
13+
14+
class State(StrictBaseModel):
15+
"""The main consensus state object."""
16+
17+
# Configuration
18+
config: Config
19+
"""The chain's configuration parameters."""
20+
21+
# Slot and block tracking
22+
slot: Uint64
23+
"""The current slot number."""
24+
25+
latest_block_header: BlockHeader
26+
"""The header of the most recent block."""
27+
28+
# Fork choice
29+
latest_justified: Checkpoint
30+
"""The latest justified checkpoint."""
31+
32+
latest_finalized: Checkpoint
33+
"""The latest finalized checkpoint."""
34+
35+
# Historical data
36+
historical_block_hashes: Annotated[
37+
list[Bytes32],
38+
Field(max_length=DEVNET_CONFIG.historical_roots_limit),
39+
]
40+
"""A list of historical block root hashes."""
41+
42+
justified_slots: Annotated[
43+
list[bool],
44+
Field(max_length=DEVNET_CONFIG.historical_roots_limit),
45+
]
46+
"""A bitfield indicating which historical slots were justified."""
47+
48+
# Justification tracking (flattened for SSZ compatibility)
49+
justifications_roots: Annotated[
50+
list[Bytes32],
51+
Field(max_length=DEVNET_CONFIG.historical_roots_limit),
52+
]
53+
"""Roots of justified blocks."""
54+
55+
justifications_validators: Annotated[
56+
list[bool],
57+
Field(
58+
max_length=(
59+
DEVNET_CONFIG.historical_roots_limit
60+
* DEVNET_CONFIG.historical_roots_limit
61+
)
62+
),
63+
]
64+
"""A bitlist of validators who participated in justifications."""
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"""Vote Containers."""
2+
3+
from lean_spec.types import Bytes32, StrictBaseModel, Uint64
4+
5+
from .checkpoint import Checkpoint
6+
7+
8+
class Vote(StrictBaseModel):
9+
"""Represents a validator's vote for chain head."""
10+
11+
validator_id: Uint64
12+
"""The index of the voting validator."""
13+
14+
slot: Uint64
15+
"""The slot for which this vote is cast."""
16+
17+
head: Checkpoint
18+
"""The validator's perceived head of the chain."""
19+
20+
target: Checkpoint
21+
"""The justified checkpoint the validator is voting for."""
22+
23+
source: Checkpoint
24+
"""The last justified checkpoint known to the validator."""
25+
26+
27+
class SignedVote(StrictBaseModel):
28+
"""A container for a vote and its corresponding signature."""
29+
30+
data: Vote
31+
"""The vote data."""
32+
33+
signature: Bytes32
34+
"""
35+
The signature of the vote data.
36+
37+
Note: Bytes32 is a placeholder; the actual signature is much larger.
38+
"""

src/lean_spec/subspecs/types/__init__.py

Lines changed: 0 additions & 9 deletions
This file was deleted.

src/lean_spec/types/__init__.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
"""Reusable type definitions for the Lean Ethereum specification."""
2+
3+
from .base import StrictBaseModel
4+
from .basispt import BasisPoint
5+
from .hash import Bytes32
6+
from .uint64 import Uint64
7+
8+
__all__ = [
9+
"Uint64",
10+
"BasisPoint",
11+
"Bytes32",
12+
"StrictBaseModel",
13+
]

src/lean_spec/types/base.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
"""Reusable, strict base models for the specification."""
2+
3+
from pydantic import BaseModel, ConfigDict
4+
5+
6+
class StrictBaseModel(BaseModel):
7+
"""A strict, immutable pydantic base model."""
8+
9+
model_config = ConfigDict(frozen=True, extra="forbid")

0 commit comments

Comments
 (0)