forked from leanEthereum/leanSpec
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbase.py
More file actions
139 lines (111 loc) · 4.18 KB
/
Copy pathbase.py
File metadata and controls
139 lines (111 loc) · 4.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
"""Base fixture definitions for Ethereum test formats."""
import hashlib
import json
from functools import cached_property
from typing import Any, ClassVar, Dict, Type
from pydantic import Field
from framework.forks import BaseFork
from lean_spec.types import CamelModel
class BaseFixture(CamelModel):
"""
Base class for all Ethereum test fixtures (consensus and execution layers).
Provides:
- Auto-registration of fixture formats
- JSON serialization with custom encoders
- Hash generation for fixtures
- Common metadata handling
This base class is layer-agnostic and can be used for both consensus
and execution layer fixtures.
"""
# Class-level registry of all fixture formats
formats: ClassVar[Dict[str, Type["BaseFixture"]]] = {}
# Fixture format metadata
format_name: ClassVar[str] = ""
"""The name of this fixture format (e.g., 'state_transition_test')."""
description: ClassVar[str] = "Unknown fixture format"
"""Human-readable description of what this fixture tests."""
# Instance fields
network: str | None = None
"""The fork/network this fixture is valid for (e.g., 'Devnet', 'Shanghai')."""
info: Dict[str, Any] = Field(default_factory=dict, alias="_info")
"""Metadata about the test (description, fork, etc.)."""
@classmethod
def __pydantic_init_subclass__(cls, **kwargs: Any) -> None:
"""
Auto-register fixture formats when subclasses are defined.
This hook is called automatically when a new subclass is created.
If the subclass defines a `format_name`, it will be registered in
the `formats` dictionary for later lookup.
"""
super().__pydantic_init_subclass__(**kwargs)
if cls.format_name:
BaseFixture.formats[cls.format_name] = cls
@cached_property
def json_dict(self) -> Dict[str, Any]:
"""
Return the JSON representation of the fixture.
Excludes the `info` field and converts snake_case to camelCase.
"""
return self.to_json(
exclude_none=True,
exclude={"info"},
)
@cached_property
def hash(self) -> str:
"""
Generate a deterministic hash for this fixture.
The hash is computed from the JSON representation to ensure
consistency across runs.
"""
json_str = json.dumps(
self.json_dict,
sort_keys=True,
separators=(",", ":"),
)
h = hashlib.sha256(json_str.encode("utf-8")).hexdigest()
return f"0x{h}"
def json_dict_with_info(self, hash_only: bool = False) -> Dict[str, Any]:
"""
Return JSON representation with the info field included.
Args:
hash_only: If True, only include the hash in _info.
Returns:
Dictionary ready for JSON serialization.
"""
dict_with_info = self.json_dict.copy()
dict_with_info["_info"] = {"hash": self.hash}
if not hash_only:
dict_with_info["_info"].update(self.info)
return dict_with_info
def fill_info(
self,
test_id: str,
description: str,
fork: BaseFork,
) -> None:
"""
Fill metadata information for this fixture.
Args:
test_id: Unique identifier for the test case.
description: Human-readable description of the test.
fork: The fork this test is valid for.
"""
if "comment" not in self.info:
self.info["comment"] = "`leanSpec` generated test"
self.info["testId"] = test_id
self.info["description"] = description
self.info["fixtureFormat"] = self.format_name
# Set network field on the fixture itself
self.network = fork.name()
@classmethod
def supports_fork(cls, fork: str) -> bool:
"""
Check if this fixture format supports the given fork.
By default, all fixtures support all forks. Override in subclasses
to restrict to specific forks.
Args:
fork: The fork name (e.g., "devnet", "shanghai").
Returns:
True if the fixture supports this fork.
"""
return True