Skip to content

Commit 52a7149

Browse files
committed
removed static blobs, cleaned code
1 parent ed71e5d commit 52a7149

34 files changed

+76
-8339
lines changed

src/ethereum_test_forks/base_fork.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Abstract base class for Ethereum forks."""
22

33
from abc import ABC, ABCMeta, abstractmethod
4-
from typing import Any, ClassVar, List, Mapping, Optional, Protocol, Sized, Tuple, Type
4+
from typing import Any, ClassVar, List, Literal, Mapping, Optional, Protocol, Sized, Tuple, Type
55

66
from semver import Version
77

@@ -155,6 +155,14 @@ class BaseFork(ABC, metaclass=BaseForkMeta):
155155
_solc_name: ClassVar[Optional[str]] = None
156156
_ignore: ClassVar[bool] = False
157157

158+
# make mypy happy
159+
BLOB_CONSTANTS: ClassVar[dict[str, int | Literal["big"]]] = {}
160+
161+
@classmethod
162+
def get_blob_constant(cls, name: str) -> int | Literal["big"]:
163+
"""Return value of requested blob constant."""
164+
raise NotImplementedError
165+
158166
def __init_subclass__(
159167
cls,
160168
*,

src/ethereum_test_types/blob.py

Lines changed: 67 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
from hashlib import sha256
66
from os.path import realpath
77
from pathlib import Path
8-
from typing import Any, ClassVar, List
8+
from typing import Any, ClassVar, List, Literal, cast
99

10-
import ckzg
10+
import ckzg # type: ignore
1111
import platformdirs
1212

1313
from ethereum_test_base_types.base_types import Bytes, Hash
@@ -20,15 +20,6 @@
2020
)
2121

2222

23-
def get_eest_root_folder(marker_files=("pyproject.toml", ".git", "tests", "src")) -> Path:
24-
"""Search for a folder where all files/folders listed above exist (root of project)."""
25-
current = Path(__file__).resolve()
26-
for parent in current.parents:
27-
if all((parent / marker).exists() for marker in marker_files):
28-
return parent
29-
raise RuntimeError("Project root folder of execution-spec-tests was not found")
30-
31-
3223
def fork_string_to_object(fork_name: str) -> type[Cancun] | type[Prague] | type[Osaka]:
3324
"""Take a fork string and return the respective fork as object."""
3425
fork_name = fork_name.lower()
@@ -42,8 +33,6 @@ def fork_string_to_object(fork_name: str) -> type[Cancun] | type[Prague] | type[
4233
raise ValueError(f"Fork {fork_name} has not yet been implemented in this function.")
4334

4435

45-
eest_root = get_eest_root_folder()
46-
4736
CACHED_BLOBS_DIRECTORY: Path = (
4837
Path(platformdirs.user_cache_dir("ethereum-execution-spec-tests")) / "cached_blobs"
4938
)
@@ -77,7 +66,7 @@ def trusted_setup(cls):
7766
@staticmethod
7867
def get_filename(fork: Fork, seed: int) -> str:
7968
"""Return filename this blob would have as string (with .json extension)."""
80-
amount_cell_proofs: int = fork.get_blob_constant("AMOUNT_CELL_PROOFS")
69+
amount_cell_proofs: int = cast(int, fork.get_blob_constant("AMOUNT_CELL_PROOFS"))
8170
return "blob_" + str(seed) + "_cell_proofs_" + str(amount_cell_proofs) + ".json"
8271

8372
@staticmethod
@@ -88,7 +77,6 @@ def get_filepath(fork: Fork, seed: int):
8877

8978
# create cached blobs dir if necessary
9079
if not CACHED_BLOBS_DIRECTORY.exists():
91-
# print(f"Blob cache directory does not exist already: {CACHED_BLOBS_DIRECTORY}. I create it now.") # noqa: E501
9280
CACHED_BLOBS_DIRECTORY.mkdir(
9381
parents=True, exist_ok=True
9482
) # create all necessary dirs on the way
@@ -97,8 +85,8 @@ def get_filepath(fork: Fork, seed: int):
9785
return CACHED_BLOBS_DIRECTORY / would_be_filename
9886

9987
@staticmethod
100-
def from_fork(fork: Fork, seed: int = 0, timestamp: int = 0) -> "Blob": # noqa: N802
101-
"""Construct Blob instances. Fork-specific logic is encapsulated within nested functions.""" # noqa: E501
88+
def from_fork(fork: Fork, seed: int = 0, timestamp: int = 0) -> "Blob":
89+
"""Construct Blob instances. Fork logic is encapsulated within nested functions."""
10290

10391
def generate_blob_data(rng_seed: int = 0) -> Bytes:
10492
"""Calculate blob data deterministically via provided seed."""
@@ -107,14 +95,14 @@ def generate_blob_data(rng_seed: int = 0) -> Bytes:
10795

10896
# generate blob
10997
ints: list[int] = [
110-
rng.randrange(fork.get_blob_constant("BLS_MODULUS"))
111-
for _ in range(fork.get_blob_constant("FIELD_ELEMENTS_PER_BLOB"))
98+
rng.randrange(cast(int, fork.get_blob_constant("BLS_MODULUS")))
99+
for _ in range(cast(int, fork.get_blob_constant("FIELD_ELEMENTS_PER_BLOB")))
112100
]
113101

114102
encoded: list[bytes] = [
115103
i.to_bytes(
116-
fork.get_blob_constant("BYTES_PER_FIELD_ELEMENT"),
117-
fork.get_blob_constant("KZG_ENDIANNESS"),
104+
cast(int, fork.get_blob_constant("BYTES_PER_FIELD_ELEMENT")),
105+
cast(Literal["big"], fork.get_blob_constant("KZG_ENDIANNESS")),
118106
)
119107
for i in ints
120108
]
@@ -127,19 +115,24 @@ def get_versioned_hash(commitment: Bytes, version: int = 1) -> Hash:
127115
return Hash(bytes([version]) + sha256(commitment).digest()[1:])
128116

129117
def get_commitment(data: Bytes) -> Bytes:
130-
"""Take a blob and returns a cryptographic commitment to it. Note: Each cell seems to hold a copy of this commitment.""" # noqa: E501
118+
"""
119+
Take a blob and returns a cryptographic commitment to it.
120+
121+
Note: Each cell seems to hold a copy of this commitment.
122+
"""
131123
# sanity check
132-
assert len(data) == fork.get_blob_constant(
133-
"FIELD_ELEMENTS_PER_BLOB"
134-
) * fork.get_blob_constant("BYTES_PER_FIELD_ELEMENT"), (
135-
f"Expected blob of length {fork.get_blob_constant('FIELD_ELEMENTS_PER_BLOB') * fork.get_blob_constant('BYTES_PER_FIELD_ELEMENT')} but got blob of length {len(data)}" # noqa: E501
124+
field_elements: int = cast(int, fork.get_blob_constant("FIELD_ELEMENTS_PER_BLOB"))
125+
bytes_per_field: int = cast(int, fork.get_blob_constant("BYTES_PER_FIELD_ELEMENT"))
126+
assert len(data) == field_elements * bytes_per_field, (
127+
f"Expected blob of length "
128+
f"{field_elements * bytes_per_field} but got blob of length {len(data)}"
136129
)
137130

138131
# calculate commitment
139132
commitment = ckzg.blob_to_kzg_commitment(data, Blob._trusted_setup)
140-
141133
assert len(commitment) == fork.get_blob_constant("BYTES_PER_COMMITMENT"), (
142-
f"Expected {fork.get_blob_constant('BYTES_PER_COMMITMENT')} resulting commitments but got {len(commitment)} commitments" # noqa: E501
134+
f"Expected {fork.get_blob_constant('BYTES_PER_COMMITMENT')} "
135+
f"resulting commitments but got {len(commitment)} commitments"
143136
)
144137

145138
return commitment
@@ -152,7 +145,7 @@ def get_proof(fork: Fork, data: Bytes) -> List[Bytes] | Bytes:
152145
if amount_cell_proofs == 0:
153146
z = 2 # 2 is one of many possible valid field elements z (https://github.com/ethereum/consensus-specs/blob/ad884507f7a1d5962cd3dfb5f7b3e41aab728c55/tests/core/pyspec/eth2spec/test/utils/kzg_tests.py#L58-L66)
154147
z_valid_size: bytes = z.to_bytes(
155-
fork.get_blob_constant("BYTES_PER_FIELD_ELEMENT"), byteorder="big"
148+
cast(int, fork.get_blob_constant("BYTES_PER_FIELD_ELEMENT")), byteorder="big"
156149
)
157150
proof, _ = ckzg.compute_kzg_proof(data, z_valid_size, Blob._trusted_setup)
158151
return proof
@@ -165,7 +158,8 @@ def get_proof(fork: Fork, data: Bytes) -> List[Bytes] | Bytes:
165158
return proofs
166159

167160
raise AssertionError(
168-
f"get_proof() has not been implemented yet for fork: {fork_str}. Got amount of cell proofs {amount_cell_proofs} but expected 128." # noqa: E501
161+
f"get_proof() has not been implemented yet for fork: {fork_str}. "
162+
f"Got amount of cell proofs {amount_cell_proofs} but expected 128."
169163
)
170164

171165
def get_cells(fork: Fork, data: Bytes) -> List[Bytes] | None:
@@ -184,7 +178,8 @@ def get_cells(fork: Fork, data: Bytes) -> List[Bytes] | None:
184178
return cells # List[bytes]
185179

186180
raise AssertionError(
187-
f"get_cells() has not been implemented yet for fork: {fork_str}. Got amount of cell proofs {amount_cell_proofs} but expected 128." # noqa: E501
181+
f"get_cells() has not been implemented yet for fork: {fork_str}. Got amount of "
182+
f"cell proofs {amount_cell_proofs} but expected 128."
188183
)
189184

190185
assert fork.supports_blobs(), f"Provided fork {fork.name()} does not support blobs!"
@@ -221,11 +216,16 @@ def get_cells(fork: Fork, data: Bytes) -> List[Bytes] | None:
221216
)
222217

223218
@staticmethod
224-
def from_file(file_name: str) -> "Blob": # noqa: N802
225-
"""Read a .json file and reconstruct object it represents. You can load a blob only via its filename (with or without .json extension).""" # noqa: E501
219+
def from_file(file_name: str) -> "Blob":
220+
"""
221+
Read a .json file and reconstruct object it represents.
222+
223+
You can load a blob only via its filename (with or without .json extension).
224+
"""
226225
# ensure filename was passed
227226
assert file_name.startswith("blob_"), (
228-
f"You provided an invalid blob filename. Expected it to start with 'blob_' but got: {file_name}" # noqa: E501
227+
f"You provided an invalid blob filename. Expected it to start with 'blob_' "
228+
f"but got: {file_name}"
229229
)
230230

231231
# loaded trusted setup if it is not already loaded
@@ -261,16 +261,17 @@ def write_to_file(self):
261261
with open(output_location, "w", encoding="utf-8") as f: # overwrite existing
262262
f.write(json_str)
263263

264-
def verify_cell_kzg_proof_batch(self, cell_indices: list) -> bool: # noqa: E501
264+
def verify_cell_kzg_proof_batch(self, cell_indices: list) -> bool:
265265
"""Check whether all cell proofs are valid and returns True only if that is the case."""
266266
assert self.fork in ["osaka"], (
267267
f"verify_cell_kzg_proof_batch() is not available for fork: {self.fork}"
268268
)
269269

270-
assert self.cells is not None, "" # TODO: write message
270+
assert self.cells is not None, "self.cells is None, critical error."
271271

272272
assert len(cell_indices) == len(self.cells), (
273-
f"Cell Indices list (detected length {len(cell_indices)}) and Cell list (detected length {len(self.cells)}) should have same length." # noqa: E501
273+
f"Cell Indices list (detected length {len(cell_indices)}) and Cell list "
274+
f"(detected length {len(self.cells)}) should have same length."
274275
)
275276

276277
# each cell refers to the same commitment
@@ -288,26 +289,30 @@ def delete_cells_then_recover_them(self, deletion_indices: list[int]):
288289
289290
Note: Requirement for successful reconstruction is having at least N of the 2N cells.
290291
291-
Theoretical Usage: You pass a cell list with to 128 elements to this function along with a list of deletion indices.
292-
These cells will be deleted and then the ckzg recovery mechanism is used to repair the missing cells.
292+
Theoretical Usage: You pass a cell list with to 128 elements to this function
293+
along with a list of deletion indices. These cells will be deleted and then
294+
the ckzg recovery mechanism is used to repair the missing cells.
293295
If no assertion is triggered the reconstruction was successful.
294-
""" # noqa: E501
296+
"""
295297
assert self.fork in ["osaka"], (
296298
f"delete_cells_then_recover_them() is not available for fork: {self.fork}"
297299
)
298300

299-
assert self.cells is not None, "..." # TODO: write text
301+
assert self.cells is not None, "self.cells is None, critical problem."
300302

301303
assert isinstance(self.proof, list), (
302-
"This function only works when self.proof is a list, but it seems to be of type bytes (not a list)" # noqa: E501
304+
"This function only works when self.proof is a list, but it seems to be "
305+
" of type bytes (not a list)"
303306
)
304307

305308
assert len(self.cells) == 128, (
306-
f"You are supposed to pass a full cell list with 128 elements to this function, but got list of length {len(self.cells)}" # noqa: E501
309+
f"You are supposed to pass a full cell list with 128 elements to this function, "
310+
f"but got list of length {len(self.cells)}"
307311
)
308312

309313
assert len(deletion_indices) < 129, (
310-
f"You can't delete more than every cell (max len of deletion indices list is 128), but you passed a deletion indices list of length {len(deletion_indices)}" # noqa: E501
314+
f"You can't delete more than every cell (max len of deletion indices list is 128), "
315+
f"but you passed a deletion indices list of length {len(deletion_indices)}"
311316
)
312317
for i in deletion_indices:
313318
assert 0 <= i <= 127, f"Expected integers in range [0, 127], but got: {i}"
@@ -319,26 +324,36 @@ def delete_cells_then_recover_them(self, deletion_indices: list[int]):
319324

320325
recovered_cells, recovered_proofs = ckzg.recover_cells_and_kzg_proofs(
321326
remaining_indices, remaining_cells, Blob._trusted_setup
322-
) # on success returns two lists of len 128 # noqa: E501
327+
) # on success returns two lists of len 128
323328

324329
# determine success/failure
325330
assert len(recovered_cells) == len(self.cells), (
326-
f"Failed to recover cell list. Original cell list had length {len(self.cells)} but recovered cell list has length {len(recovered_cells)}" # noqa: E501
331+
f"Failed to recover cell list. Original cell list had length {len(self.cells)} but "
332+
f"recovered cell list has length {len(recovered_cells)}"
327333
)
328334
assert len(recovered_proofs) == len(self.proof), (
329-
f"Failed to recover proofs list. Original proofs list had length {len(self.proof)} but recovered proofs list has length {len(recovered_proofs)}" # noqa: E501
335+
f"Failed to recover proofs list. Original proofs list had length {len(self.proof)} "
336+
f"but recovered proofs list has length {len(recovered_proofs)}"
330337
)
331338

332339
for i in range(len(recovered_cells)):
333340
assert self.cells[i] == recovered_cells[i], (
334-
f"Failed to correctly restore missing cells. At index {i} original cell was 0x{self.cells[i].hex()} but reconstructed cell does not match: 0x{recovered_cells[i].hex()}" # noqa: E501
341+
f"Failed to correctly restore missing cells. At index {i} original cell was "
342+
f"0x{self.cells[i].hex()} but reconstructed cell does not match: "
343+
f"0x{recovered_cells[i].hex()}"
335344
)
336345
assert self.proof[i] == recovered_proofs[i], (
337-
f"Failed to correctly restore missing proofs. At index {i} original proof was 0x{self.proof[i].hex()} but reconstructed proof does not match: 0x{recovered_proofs[i].hex()}" # noqa: E501
346+
f"Failed to correctly restore missing proofs. At index {i} original proof was "
347+
f"0x{self.proof[i].hex()} but reconstructed proof does not match: "
348+
f"0x{recovered_proofs[i].hex()}"
338349
)
339350

340351
class ProofCorruptionMode(Enum):
341-
"""Define what the proof corruption modes do. For Osaka and later each Bytes object in the list is manipulated this way.""" # noqa: E501
352+
"""
353+
Define what the proof corruption modes do.
354+
355+
For Osaka and later each Bytes object in the list is manipulated this way.
356+
"""
342357

343358
CORRUPT_FIRST_BYTE = 1 # corrupts a single byte (index 0)
344359
CORRUPT_LAST_BYTE = 2 # corrupts a single byte (last valid index)
@@ -470,12 +485,14 @@ def corrupt_byte(b: bytes) -> Bytes:
470485
# osaka
471486
testseed = 55
472487
ddd: Blob = Blob.from_fork(Osaka, testseed + 10)
488+
assert isinstance(ddd.proof[0], bytes) # mypy fix
473489
oldValue = ddd.proof[0][5]
474490
for m in Blob.ProofCorruptionMode:
475491
ddd.corrupt_proof(m)
476492
print("proof corruption works (osaka):", oldValue != ddd.proof[0][5])
477493
# prague
478494
eeeeeeeeee: Blob = Blob.from_fork(Prague, testseed + 11)
495+
assert isinstance(eeeeeeeeee.proof[5], int) # mypy fix
479496
oldValue = eeeeeeeeee.proof[5]
480497
for m in Blob.ProofCorruptionMode:
481498
eeeeeeeeee.corrupt_proof(m)

tests/cancun/eip4844_blobs/static_blobs/.gitkeep

Whitespace-only changes.

tests/osaka/eip7594_peerdas/static_blobs/blob_0.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

tests/osaka/eip7594_peerdas/static_blobs/blob_1.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

tests/osaka/eip7594_peerdas/static_blobs/blob_2.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

tests/osaka/eip7594_peerdas/static_blobs/blob_3.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

tests/osaka/eip7594_peerdas/static_blobs/blob_4.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

tests/osaka/eip7594_peerdas/static_blobs/blob_5.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

tests/osaka/eip7594_peerdas/static_blobs/blob_6.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)