Skip to content

Commit 6fd90a8

Browse files
spencer-tbmarioevz
andauthored
feat(forks|consume): bpo framework requirements (#2050)
* feat(tests): add bpo transtion test with 7918 reserve trigger. * chore: ruleset tweak. * feat(forks): Add BPO2, BPO3 * feat(ruleset): Add BPO2, BPO3 * fix: ruleset copy-paste error * fix(plugins): Update mapper * feat(forks): Add `blob_reserve_price_active`, `blob_base_cost` * chore(tests): cherry pick updates. * feat(forks): Add BPO4 (Decreases blob parameters) * fix(ruleset): Add BPO4 * fix(eels_resolutions): Add BPO4 * feat(forks): Add `bpo_fork` property to forks * feat(plugins/fork): Add `valid_for_bpo_forks` validity marker * feat(ci): develop feature fills until BPO3 * fix(forks): Fix marker, add unit test * fix(forks): Fix marker again * chore(ci): bump eels res, fill until bpo4. * chore(docs): changelog. * chore(ci): revert back to use BPO3 for release currently. * chore(ci): bump eels in tox verify. --------- Co-authored-by: Mario Vega <[email protected]>
1 parent 9765b91 commit 6fd90a8

File tree

16 files changed

+522
-26
lines changed

16 files changed

+522
-26
lines changed

.github/configs/eels_resolutions.json

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,20 @@
3333
"path": "$GITHUB_WORKSPACE/execution-specs/"
3434
},
3535
"Osaka": {
36-
"git_url": "https://github.com/spencer-tb/execution-specs.git",
37-
"branch": "forks/osaka",
38-
"commit": "0e97247a9022b8c04c01e22cae6ec95d1b590838"
36+
"git_url": "https://github.com/marioevz/execution-specs.git",
37+
"branch": "forks/bpo1",
38+
"commit": "3387e5f4aedfe99becfdc39b444d6371e25e0924"
39+
},
40+
"BPO1": {
41+
"same_as": "Osaka"
42+
},
43+
"BPO2": {
44+
"same_as": "Osaka"
45+
},
46+
"BPO3": {
47+
"same_as": "Osaka"
48+
},
49+
"BPO4": {
50+
"same_as": "Osaka"
3951
}
4052
}

.github/configs/feature.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ stable:
55

66
develop:
77
evm-type: develop
8-
fill-params: --until=Osaka --fill-static-tests --ignore=tests/static/state_tests/stQuadraticComplexityTest
8+
fill-params: --until=BPO3 --fill-static-tests --ignore=tests/static/state_tests/stQuadraticComplexityTest
99

1010
benchmark:
1111
evm-type: benchmark # Evmone only fully supports up to Prague

.github/workflows/tox_verify.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,8 @@ jobs:
123123
- name: Checkout ethereum/execution-specs for local EELS implementation
124124
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
125125
with:
126-
repository: ethereum/execution-specs
127-
ref: 5a49b2f39a909be6a8c84bb70611febdc2b2fd98
126+
repository: marioevz/execution-specs
127+
ref: 3387e5f4aedfe99becfdc39b444d6371e25e0924
128128
path: execution-specs
129129
fetch-depth: 1
130130
- name: Install uv ${{ vars.UV_VERSION }} and python ${{ matrix.python }}
@@ -166,8 +166,8 @@ jobs:
166166
- name: Checkout ethereum/execution-specs for local EELS implementation
167167
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
168168
with:
169-
repository: ethereum/execution-specs
170-
ref: 5a49b2f39a909be6a8c84bb70611febdc2b2fd98
169+
repository: marioevz/execution-specs
170+
ref: 3387e5f4aedfe99becfdc39b444d6371e25e0924
171171
path: execution-specs
172172
fetch-depth: 1
173173
- name: Install uv ${{ vars.UV_VERSION }} and python ${{ matrix.python }}

docs/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ Users can select any of the artifacts depending on their testing needs for their
8484
- ✨ Static tests can now be filled in every format using `--generate-all-formats` ([#2006](https://github.com/ethereum/execution-spec-tests/pull/2006)).
8585
- 💥 Flag `--flat-output` has been removed due to having been unneeded for an extended period of time ([#2018](https://github.com/ethereum/execution-spec-tests/pull/2018)).
8686
- ✨ Add support for `BlockchainEngineSyncFixture` format for tests marked with `pytest.mark.verify_sync` to enable client synchronization testing via `consume sync` command ([#2007](https://github.com/ethereum/execution-spec-tests/pull/2007)).
87+
- ✨ Framework is updated to include BPO ([EIP-7892](https://eips.ethereum.org/EIPS/eip-7892)) fork markers to enable the filling of BPO tests ([#2050](https://github.com/ethereum/execution-spec-tests/pull/2050)).
8788

8889
#### `consume`
8990

@@ -95,6 +96,7 @@ Users can select any of the artifacts depending on their testing needs for their
9596
- 🔀 Add exponential retry logic to initial fcu within consume engine ([#1815](https://github.com/ethereum/execution-spec-tests/pull/1815)).
9697
- ✨ Add `consume sync` command to test client synchronization capabilities by having one client sync from another via Engine API and P2P networking ([#2007](https://github.com/ethereum/execution-spec-tests/pull/2007)).
9798
- 💥 Removed the `consume hive` command, this was a convenience command that ran `consume rlp` and `consume engine` in one pytest session; the individual commands should now be used instead ([#2008](https://github.com/ethereum/execution-spec-tests/pull/2008)).
99+
- ✨ Update the hive ruleset to include BPO ([EIP-7892](https://eips.ethereum.org/EIPS/eip-7892)) forks ([#2050](https://github.com/ethereum/execution-spec-tests/pull/2050)).
98100

99101
#### `execute`
100102

src/ethereum_test_forks/__init__.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
from .base_fork import ForkAttribute
44
from .forks.forks import (
5+
BPO1,
6+
BPO2,
7+
BPO3,
8+
BPO4,
59
ArrowGlacier,
610
Berlin,
711
Byzantium,
@@ -22,7 +26,11 @@
2226
)
2327
from .forks.transition import (
2428
BerlinToLondonAt5,
29+
BPO1ToBPO2AtTime15k,
30+
BPO2ToBPO3AtTime15k,
31+
BPO3ToBPO4AtTime15k,
2532
CancunToPragueAtTime15k,
33+
OsakaToBPO1AtTime15k,
2634
ParisToShanghaiAtTime15k,
2735
PragueToOsakaAtTime15k,
2836
ShanghaiToCancunAtTime15k,
@@ -80,6 +88,14 @@
8088
"Prague",
8189
"PragueToOsakaAtTime15k",
8290
"Osaka",
91+
"OsakaToBPO1AtTime15k",
92+
"BPO1",
93+
"BPO1ToBPO2AtTime15k",
94+
"BPO2",
95+
"BPO2ToBPO3AtTime15k",
96+
"BPO3",
97+
"BPO3ToBPO4AtTime15k",
98+
"BPO4",
8399
"get_transition_forks",
84100
"forks_from",
85101
"forks_from_until",

src/ethereum_test_forks/base_fork.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ class BaseFork(ABC, metaclass=BaseForkMeta):
165165
_transition_tool_name: ClassVar[Optional[str]] = None
166166
_solc_name: ClassVar[Optional[str]] = None
167167
_ignore: ClassVar[bool] = False
168+
_bpo_fork: ClassVar[bool] = False
168169

169170
# make mypy happy
170171
BLOB_CONSTANTS: ClassVar[Dict[str, Union[int, Literal["big"]]]] = {}
@@ -180,11 +181,13 @@ def __init_subclass__(
180181
transition_tool_name: Optional[str] = None,
181182
solc_name: Optional[str] = None,
182183
ignore: bool = False,
184+
bpo_fork: bool = False,
183185
) -> None:
184186
"""Initialize new fork with values that don't carry over to subclass forks."""
185187
cls._transition_tool_name = transition_tool_name
186188
cls._solc_name = solc_name
187189
cls._ignore = ignore
190+
cls._bpo_fork = bpo_fork
188191

189192
# Header information abstract methods
190193
@classmethod
@@ -336,6 +339,18 @@ def max_blobs_per_block(cls, block_number: int = 0, timestamp: int = 0) -> int:
336339
"""Return the max blobs per block at a given fork."""
337340
pass
338341

342+
@classmethod
343+
@abstractmethod
344+
def blob_reserve_price_active(cls, block_number: int = 0, timestamp: int = 0) -> bool:
345+
"""Return whether the fork uses a reserve price mechanism for blobs or not."""
346+
pass
347+
348+
@classmethod
349+
@abstractmethod
350+
def blob_base_cost(cls, block_number: int = 0, timestamp: int = 0) -> int:
351+
"""Return the base cost of a blob at a given fork."""
352+
pass
353+
339354
@classmethod
340355
@abstractmethod
341356
def full_blob_tx_wrapper_version(cls, block_number: int = 0, timestamp: int = 0) -> int | None:
@@ -601,6 +616,12 @@ def ignore(cls) -> bool:
601616
"""Return whether the fork should be ignored during test generation."""
602617
return cls._ignore
603618

619+
@classmethod
620+
@prefer_transition_to_method
621+
def bpo_fork(cls) -> bool:
622+
"""Return whether the fork is a BPO fork."""
623+
return cls._bpo_fork
624+
604625
@classmethod
605626
def parent(cls) -> Type["BaseFork"] | None:
606627
"""Return the parent fork."""

src/ethereum_test_forks/forks/forks.py

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,16 @@ def max_blobs_per_block(cls, block_number: int = 0, timestamp: int = 0) -> int:
250250
"""Return the max number of blobs per block at a given fork."""
251251
raise NotImplementedError(f"Max blobs per block is not supported in {cls.name()}")
252252

253+
@classmethod
254+
def blob_reserve_price_active(cls, block_number: int = 0, timestamp: int = 0) -> bool:
255+
"""Return whether the fork uses a reserve price mechanism for blobs or not."""
256+
raise NotImplementedError(f"Blob reserve price is not supported in {cls.name()}")
257+
258+
@classmethod
259+
def blob_base_cost(cls, block_number: int = 0, timestamp: int = 0) -> int:
260+
"""Return the base cost of a blob at a given fork."""
261+
raise NotImplementedError(f"Blob base cost is not supported in {cls.name()}")
262+
253263
@classmethod
254264
def full_blob_tx_wrapper_version(cls, block_number: int = 0, timestamp: int = 0) -> int | None:
255265
"""Return the version of the full blob transaction wrapper."""
@@ -1052,6 +1062,11 @@ def max_blobs_per_block(cls, block_number: int = 0, timestamp: int = 0) -> int:
10521062
"""Blobs are enabled starting from Cancun, with a static max of 6 blobs per block."""
10531063
return 6
10541064

1065+
@classmethod
1066+
def blob_reserve_price_active(cls, block_number: int = 0, timestamp: int = 0) -> bool:
1067+
"""Blob reserve price is not supported in Cancun."""
1068+
return False
1069+
10551070
@classmethod
10561071
def full_blob_tx_wrapper_version(cls, block_number: int = 0, timestamp: int = 0) -> int | None:
10571072
"""Pre-Osaka forks don't use tx wrapper versions for full blob transactions."""
@@ -1534,6 +1549,92 @@ def max_blobs_per_tx(cls, block_number: int = 0, timestamp: int = 0) -> int:
15341549
"""Blobs in Osaka, have a static max of 6 blobs per tx. Differs from the max per block."""
15351550
return 6
15361551

1552+
@classmethod
1553+
def blob_reserve_price_active(cls, block_number: int = 0, timestamp: int = 0) -> bool:
1554+
"""Blob reserve price is supported in Osaka."""
1555+
return True
1556+
1557+
@classmethod
1558+
def blob_base_cost(cls, block_number: int = 0, timestamp: int = 0) -> int:
1559+
"""Return the base cost of a blob at a given fork."""
1560+
return 2**13 # EIP-7918 new parameter
1561+
1562+
1563+
class BPO1(Osaka, bpo_fork=True):
1564+
"""BPO1 fork - Blob Parameter Only fork 1."""
1565+
1566+
@classmethod
1567+
def blob_base_fee_update_fraction(cls, block_number: int = 0, timestamp: int = 0) -> int:
1568+
"""Return the blob base fee update fraction for BPO1."""
1569+
return 8832827
1570+
1571+
@classmethod
1572+
def target_blobs_per_block(cls, block_number: int = 0, timestamp: int = 0) -> int:
1573+
"""Blobs in BPO1 have a target of 9 blobs per block."""
1574+
return 9
1575+
1576+
@classmethod
1577+
def max_blobs_per_block(cls, block_number: int = 0, timestamp: int = 0) -> int:
1578+
"""Blobs in BPO1 have a max of 14 blobs per block."""
1579+
return 14
1580+
1581+
1582+
class BPO2(BPO1, bpo_fork=True):
1583+
"""BPO2 fork - Blob Parameter Only fork 2."""
1584+
1585+
@classmethod
1586+
def blob_base_fee_update_fraction(cls, block_number: int = 0, timestamp: int = 0) -> int:
1587+
"""Return the blob base fee update fraction for BPO2."""
1588+
return 13739630
1589+
1590+
@classmethod
1591+
def target_blobs_per_block(cls, block_number: int = 0, timestamp: int = 0) -> int:
1592+
"""Blobs in BPO2 have a target of 14 blobs per block."""
1593+
return 14
1594+
1595+
@classmethod
1596+
def max_blobs_per_block(cls, block_number: int = 0, timestamp: int = 0) -> int:
1597+
"""Blobs in BPO2 have a max of 21 blobs per block."""
1598+
return 21
1599+
1600+
1601+
class BPO3(BPO2, bpo_fork=True):
1602+
"""BPO3 fork - Blob Parameter Only fork 3."""
1603+
1604+
@classmethod
1605+
def blob_base_fee_update_fraction(cls, block_number: int = 0, timestamp: int = 0) -> int:
1606+
"""Return the blob base fee update fraction for BPO3."""
1607+
return 20609697
1608+
1609+
@classmethod
1610+
def target_blobs_per_block(cls, block_number: int = 0, timestamp: int = 0) -> int:
1611+
"""Blobs in BPO3 have a target of 21 blobs per block."""
1612+
return 21
1613+
1614+
@classmethod
1615+
def max_blobs_per_block(cls, block_number: int = 0, timestamp: int = 0) -> int:
1616+
"""Blobs in BPO3 have a max of 32 blobs per block."""
1617+
return 32
1618+
1619+
1620+
class BPO4(BPO3, bpo_fork=True):
1621+
"""BPO4 fork - Blob Parameter Only fork 4."""
1622+
1623+
@classmethod
1624+
def blob_base_fee_update_fraction(cls, block_number: int = 0, timestamp: int = 0) -> int:
1625+
"""Return the blob base fee update fraction for BPO4."""
1626+
return 13739630
1627+
1628+
@classmethod
1629+
def target_blobs_per_block(cls, block_number: int = 0, timestamp: int = 0) -> int:
1630+
"""Blobs in BPO4 have a target of 14 blobs per block."""
1631+
return 14
1632+
1633+
@classmethod
1634+
def max_blobs_per_block(cls, block_number: int = 0, timestamp: int = 0) -> int:
1635+
"""Blobs in BPO4 have a max of 21 blobs per block."""
1636+
return 21
1637+
15371638

15381639
class EOFv1(Prague, solc_name="cancun"):
15391640
"""EOF fork."""

src/ethereum_test_forks/forks/transition.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""List of all transition fork definitions."""
22

33
from ..transition_base_fork import transition_fork
4-
from .forks import Berlin, Cancun, London, Osaka, Paris, Prague, Shanghai
4+
from .forks import BPO1, BPO2, BPO3, BPO4, Berlin, Cancun, London, Osaka, Paris, Prague, Shanghai
55

66

77
# Transition Forks
@@ -38,3 +38,31 @@ class PragueToOsakaAtTime15k(Prague):
3838
"""Prague to Osaka transition at Timestamp 15k."""
3939

4040
pass
41+
42+
43+
@transition_fork(to_fork=BPO1, at_timestamp=15_000)
44+
class OsakaToBPO1AtTime15k(Osaka):
45+
"""Osaka to BPO1 transition at Timestamp 15k."""
46+
47+
pass
48+
49+
50+
@transition_fork(to_fork=BPO2, at_timestamp=15_000)
51+
class BPO1ToBPO2AtTime15k(BPO1):
52+
"""BPO1 to BPO2 transition at Timestamp 15k."""
53+
54+
pass
55+
56+
57+
@transition_fork(to_fork=BPO3, at_timestamp=15_000)
58+
class BPO2ToBPO3AtTime15k(BPO2):
59+
"""BPO2 to BPO3 transition at Timestamp 15k."""
60+
61+
pass
62+
63+
64+
@transition_fork(to_fork=BPO4, at_timestamp=15_000)
65+
class BPO3ToBPO4AtTime15k(BPO3):
66+
"""BPO3 to BPO4 transition at Timestamp 15k."""
67+
68+
pass

src/ethereum_test_forks/tests/test_forks.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
from ethereum_test_base_types import BlobSchedule
99

1010
from ..forks.forks import (
11+
BPO1,
12+
BPO2,
13+
BPO3,
14+
BPO4,
1115
Berlin,
1216
Cancun,
1317
Frontier,
@@ -21,7 +25,11 @@
2125
)
2226
from ..forks.transition import (
2327
BerlinToLondonAt5,
28+
BPO1ToBPO2AtTime15k,
29+
BPO2ToBPO3AtTime15k,
30+
BPO3ToBPO4AtTime15k,
2431
CancunToPragueAtTime15k,
32+
OsakaToBPO1AtTime15k,
2533
ParisToShanghaiAtTime15k,
2634
PragueToOsakaAtTime15k,
2735
ShanghaiToCancunAtTime15k,
@@ -472,3 +480,15 @@ def test_blob_schedules(fork: Fork, expected_schedule: Dict | None):
472480
assert fork.blob_schedule() is None
473481
else:
474482
assert fork.blob_schedule() == BlobSchedule(**expected_schedule)
483+
484+
485+
def test_bpo_fork(): # noqa: D103
486+
assert Osaka.bpo_fork() is False
487+
assert BPO1.bpo_fork() is True
488+
assert BPO2.bpo_fork() is True
489+
assert BPO3.bpo_fork() is True
490+
assert BPO4.bpo_fork() is True
491+
assert OsakaToBPO1AtTime15k.bpo_fork() is True
492+
assert BPO1ToBPO2AtTime15k.bpo_fork() is True
493+
assert BPO2ToBPO3AtTime15k.bpo_fork() is True
494+
assert BPO3ToBPO4AtTime15k.bpo_fork() is True

src/ethereum_test_forks/transition_base_fork.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def transition_method(
8282

8383
return classmethod(transition_method)
8484

85-
for method_name in base_fork_abstract_methods():
85+
for method_name in base_fork_abstract_methods() + ["bpo_fork"]:
8686
setattr(
8787
NewTransitionClass,
8888
method_name,

0 commit comments

Comments
 (0)