Skip to content

Commit 18b3d88

Browse files
spencer-tbmarioevz
andcommitted
feat(fw|tests): add changes for verkle transition tests. (#507)
* feat(fw|tests): add changes for verkle transition tests. --------- Co-authored-by: Mario Vega <[email protected]>
1 parent 09607ac commit 18b3d88

File tree

23 files changed

+615
-69
lines changed

23 files changed

+615
-69
lines changed

src/ethereum_test_forks/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
Cancun,
1111
Constantinople,
1212
ConstantinopleFix,
13+
EIP6800Transition,
1314
Frontier,
1415
GrayGlacier,
1516
Homestead,
@@ -19,6 +20,7 @@
1920
Paris,
2021
Prague,
2122
Shanghai,
23+
ShanghaiEIP6800,
2224
)
2325
from .forks.transition import (
2426
BerlinToLondonAt5,
@@ -60,6 +62,8 @@
6062
"MuirGlacier",
6163
"Shanghai",
6264
"ShanghaiToCancunAtTime15k",
65+
"ShanghaiEIP6800",
66+
"EIP6800Transition",
6367
"Cancun",
6468
"Prague",
6569
"get_transition_forks",

src/ethereum_test_forks/base_fork.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,22 @@ def pre_allocation_blockchain(cls) -> Mapping:
221221
"""
222222
pass
223223

224+
@classmethod
225+
@abstractmethod
226+
def environment_verkle_conversion_starts(cls) -> bool:
227+
"""
228+
Returns true if the fork starts the verkle conversion process.
229+
"""
230+
pass
231+
232+
@classmethod
233+
@abstractmethod
234+
def environment_verkle_conversion_completed(cls) -> bool:
235+
"""
236+
Returns true if verkle conversion must have been completed by this fork.
237+
"""
238+
pass
239+
224240
# Engine API information abstract methods
225241
@classmethod
226242
@abstractmethod
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
"""
2+
Constant values used by the forks.
3+
"""
4+
5+
from typing import Dict, Generator, Iterator, Mapping, Tuple
6+
7+
from Crypto.Hash import SHA256
8+
9+
# TODO: Use for large verkle conversion init MPT
10+
MAX_ACCOUNTS = 1000
11+
MAX_NONCE = 2**64 - 1
12+
MAX_BALANCE = 2**256 - 1
13+
MAX_STORAGE_SLOTS_PER_ACCOUNT = 1000
14+
MAX_ACCOUNT_CODE_SIZE = 2**14 + 2**13 # EIP-170
15+
16+
17+
def seed_generator(seed: int) -> Generator[int, None, None]:
18+
"""
19+
Generate a seed using the SHA256 hash function.
20+
"""
21+
seed = int.from_bytes(
22+
bytes=SHA256.new(data=seed.to_bytes(length=256, byteorder="big")).digest(), byteorder="big"
23+
)
24+
while True:
25+
yield seed
26+
seed = int.from_bytes(
27+
bytes=SHA256.new(data=seed.to_bytes(length=256, byteorder="big")).digest(),
28+
byteorder="big",
29+
)
30+
31+
32+
def storage_generator(
33+
seed: Iterator[int], max_slots: int
34+
) -> Generator[Tuple[int, int], None, None]:
35+
"""
36+
Generate storage slots for an account.
37+
"""
38+
MAX_KEY_VALUE = 2**256 - 1
39+
for _ in range(max_slots):
40+
yield next(seed) % MAX_KEY_VALUE, next(seed) % MAX_KEY_VALUE
41+
42+
43+
def account_generator(
44+
seed: Iterator[int], max_accounts: int
45+
) -> Generator[Tuple[int, Dict[str, str | int | Dict[int, int]]], None, None]:
46+
"""
47+
Generate accounts.
48+
"""
49+
for _ in range(max_accounts):
50+
storage_g = storage_generator(seed, next(seed) % MAX_STORAGE_SLOTS_PER_ACCOUNT)
51+
yield next(seed) % 2**160, {
52+
"nonce": next(seed) % MAX_NONCE,
53+
"balance": next(seed) % MAX_BALANCE,
54+
"storage": {k: v for k, v in storage_g},
55+
"code": "0x" + "00" * 32,
56+
}
57+
58+
59+
VERKLE_PRE_ALLOCATION: Mapping = {
60+
addr: account
61+
for addr, account in account_generator(seed=seed_generator(0), max_accounts=MAX_ACCOUNTS)
62+
}

src/ethereum_test_forks/forks/forks.py

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from semver import Version
1111

1212
from ..base_fork import BaseFork
13+
from ..transition_base_fork import transition_fork
1314

1415
CURRENT_FILE = Path(realpath(__file__))
1516
CURRENT_FOLDER = CURRENT_FILE.parent
@@ -188,6 +189,20 @@ def pre_allocation_blockchain(cls) -> Mapping:
188189
"""
189190
return {}
190191

192+
@classmethod
193+
def environment_verkle_conversion_starts(cls) -> bool:
194+
"""
195+
Returns true if the fork starts the verkle conversion process.
196+
"""
197+
return False
198+
199+
@classmethod
200+
def environment_verkle_conversion_completed(cls) -> bool:
201+
"""
202+
Returns true if verkle conversion must have been completed by this fork.
203+
"""
204+
return False
205+
191206

192207
class Homestead(Frontier):
193208
"""
@@ -604,7 +619,65 @@ def engine_forkchoice_updated_version(
604619
return 3
605620

606621

607-
class CancunEIP7692( # noqa: SC200
622+
class ShanghaiEIP6800(
623+
Shanghai,
624+
transition_tool_name="Prague",
625+
blockchain_test_network_name="Prague",
626+
solc_name="shanghai",
627+
):
628+
"""
629+
Shanghai + EIP-6800 (Verkle) fork
630+
"""
631+
632+
@classmethod
633+
def is_deployed(cls) -> bool:
634+
"""
635+
Flags that the fork has not been deployed to mainnet; it is under active
636+
development.
637+
"""
638+
return False
639+
640+
@classmethod
641+
def environment_verkle_conversion_completed(cls) -> bool:
642+
"""
643+
Verkle conversion has already completed in this fork.
644+
"""
645+
return True
646+
647+
@classmethod
648+
def pre_allocation_blockchain(cls) -> Mapping:
649+
"""
650+
Verkle requires pre-allocation of the history storage contract for EIP-2935 on blockchain
651+
type tests.
652+
"""
653+
new_allocation = {
654+
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE: {
655+
"nonce": 1,
656+
"code": (
657+
"0x60203611603157600143035f35116029575f35612000014311602957612000"
658+
"5f3506545f5260205ff35b5f5f5260205ff35b5f5ffd00"
659+
),
660+
}
661+
}
662+
# TODO: Utilize when testing for large init MPT
663+
# return VERKLE_PRE_ALLOCATION | super(Shanghai, cls).pre_allocation()
664+
return new_allocation | super(Shanghai, cls).pre_allocation_blockchain()
665+
666+
667+
# TODO: move back to transition.py after filling and executing ShanghaiEIP6800 tests successfully
668+
@transition_fork(to_fork=ShanghaiEIP6800, at_timestamp=32)
669+
class EIP6800Transition(
670+
Shanghai,
671+
blockchain_test_network_name="ShanghaiToPragueAtTime32",
672+
):
673+
"""
674+
Shanghai to Verkle transition at Timestamp 32.
675+
"""
676+
677+
pass
678+
679+
680+
class CancunEIP7692(
608681
Cancun,
609682
transition_tool_name="Prague", # Evmone enables (only) EOF at Prague
610683
blockchain_test_network_name="Prague", # Evmone enables (only) EOF at Prague

src/ethereum_test_forks/forks/transition.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
"""
22
List of all transition fork definitions.
33
"""
4+
45
from ..transition_base_fork import transition_fork
56
from .forks import Berlin, Cancun, London, Paris, Prague, Shanghai
67

78

8-
# Transition Forks
99
@transition_fork(to_fork=London, at_block=5)
1010
class BerlinToLondonAt5(Berlin):
1111
"""

src/ethereum_test_forks/helpers.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""
22
Helper methods to resolve forks during test filling
33
"""
4+
45
from typing import List, Optional
56

67
from semver import Version
@@ -32,6 +33,9 @@ def get_forks() -> List[Fork]:
3233
continue
3334
if issubclass(fork, BaseFork) and fork is not BaseFork:
3435
all_forks.append(fork)
36+
37+
all_forks += get_transition_forks(always_execute=True)
38+
3539
return all_forks
3640

3741

@@ -87,7 +91,7 @@ def get_closest_fork_with_solc_support(fork: Fork, solc_version: Version) -> Opt
8791
)
8892

8993

90-
def get_transition_forks() -> List[Fork]:
94+
def get_transition_forks(always_execute: bool = False) -> List[Fork]:
9195
"""
9296
Returns all the transition forks
9397
"""
@@ -98,6 +102,8 @@ def get_transition_forks() -> List[Fork]:
98102
if not isinstance(fork, type):
99103
continue
100104
if issubclass(fork, TransitionBaseClass) and issubclass(fork, BaseFork):
105+
if always_execute and not fork.always_execute():
106+
continue
101107
transition_forks.append(fork)
102108

103109
return transition_forks

src/ethereum_test_forks/transition_base_fork.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@ def transitions_from(cls) -> Fork:
3030
"""
3131
raise Exception("Not implemented")
3232

33+
@classmethod
34+
def always_execute(cls) -> bool:
35+
"""
36+
Whether the transition fork should be treated as a normal fork and all tests should
37+
be filled with it.
38+
"""
39+
raise Exception("Not implemented")
40+
3341

3442
def base_fork_abstract_methods() -> List[str]:
3543
"""
@@ -38,7 +46,9 @@ def base_fork_abstract_methods() -> List[str]:
3846
return list(getattr(BaseFork, "__abstractmethods__"))
3947

4048

41-
def transition_fork(to_fork: Fork, at_block: int = 0, at_timestamp: int = 0):
49+
def transition_fork(
50+
to_fork: Fork, at_block: int = 0, at_timestamp: int = 0, always_execute: bool = False
51+
):
4252
"""
4353
Decorator to mark a class as a transition fork.
4454
"""
@@ -102,6 +112,7 @@ def transition_method(
102112

103113
NewTransitionClass.transitions_to = lambda: to_fork # type: ignore
104114
NewTransitionClass.transitions_from = lambda: from_fork # type: ignore
115+
NewTransitionClass.always_execute = lambda: always_execute # type: ignore
105116
NewTransitionClass.fork_at = lambda block_number=0, timestamp=0: ( # type: ignore
106117
to_fork if block_number >= at_block and timestamp >= at_timestamp else from_fork
107118
)

src/ethereum_test_tools/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
TestPrivateKey,
3232
TestPrivateKey2,
3333
Transaction,
34+
VerkleTree,
3435
Withdrawal,
3536
WithdrawalRequest,
3637
add_kzg_version,
@@ -115,6 +116,7 @@
115116
"TransactionException",
116117
"Withdrawal",
117118
"WithdrawalRequest",
119+
"VerkleTree",
118120
"Yul",
119121
"YulCompiler",
120122
"add_kzg_version",

src/ethereum_test_tools/common/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
Requests,
4747
Storage,
4848
Transaction,
49+
VerkleTree,
4950
Withdrawal,
5051
WithdrawalRequest,
5152
)
@@ -78,6 +79,7 @@
7879
"TestPrivateKey",
7980
"TestPrivateKey2",
8081
"Transaction",
82+
"VerkleTree",
8183
"Withdrawal",
8284
"WithdrawalRequest",
8385
"ZeroPaddedHexNumber",

0 commit comments

Comments
 (0)