Skip to content

Commit 481f7b1

Browse files
committed
port intrinsic transaction gas tests from Ori
1 parent f60f526 commit 481f7b1

File tree

5 files changed

+199
-3734
lines changed

5 files changed

+199
-3734
lines changed

converted-ethereum-tests.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
([#1535](https://github.com/ethereum/execution-spec-tests/pull/1535))
2+
GeneralStateTests/stEIP1559/intrinsicCancun.json
3+
BlockchainTests/InvalidBlocks/bcEIP1559/intrinsicOrFailCancun.json
4+
15
([#1056](https://github.com/ethereum/execution-spec-tests/pull/1056))
26
GeneralStateTests/VMTests/vmTests/calldatacopy.json
37

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""Defines EIP-2930 specification constants and functions."""
2+
3+
from dataclasses import dataclass
4+
5+
6+
@dataclass(frozen=True)
7+
class ReferenceSpec:
8+
"""Defines the reference spec version and git path."""
9+
10+
git_path: str
11+
version: str
12+
13+
14+
ref_spec_2930 = ReferenceSpec("EIPS/eip-2930.md", "c9db53a936c5c9cbe2db32ba0d1b86c4c6e73534")
15+
16+
17+
# Constants
18+
@dataclass(frozen=True)
19+
class Spec:
20+
"""
21+
Parameters from the EIP-2930 specifications as defined at
22+
https://eips.ethereum.org/EIPS/eip-2930#specification.
23+
"""
24+
25+
ACCESS_LIST_ADDRESS_COST = 2400
26+
ACCESS_LIST_STORAGE_KEY_COST = 1900
27+
28+
"""From EIP-2028"""
29+
TX_BASE_INTRINSIC_GAS = 21_000
30+
TX_DATA_ZERO_BYTE_GAS = 4
31+
TX_DATA_NON_ZERO_BYTE_GAS = 16
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
"""
2+
abstract: Tests [EIP-2930: Access list transaction](https://eips.ethereum.org/EIPS/eip-2930).
3+
Original test by Ori: https://github.com/ethereum/tests/blob/v15.0/src/GeneralStateTestsFiller/stEIP1559/intrinsicGen.js.
4+
"""
5+
6+
from typing import List
7+
8+
import pytest
9+
10+
from ethereum_test_forks import Fork
11+
from ethereum_test_tools import (
12+
AccessList,
13+
Address,
14+
Alloc,
15+
Bytes,
16+
Environment,
17+
StateTestFiller,
18+
Transaction,
19+
TransactionException,
20+
)
21+
from ethereum_test_tools import Opcodes as Op
22+
23+
from .spec import ref_spec_2930
24+
25+
REFERENCE_SPEC_GIT_PATH = ref_spec_2930.git_path
26+
REFERENCE_SPEC_VERSION = ref_spec_2930.version
27+
28+
pytestmark = pytest.mark.valid_from("Berlin")
29+
30+
31+
@pytest.mark.parametrize(
32+
"data",
33+
[
34+
pytest.param(Bytes(b""), id="data_empty"),
35+
pytest.param(Bytes(b"0x00"), id="data_1_zero_byte"),
36+
pytest.param(Bytes(b"0x00000000"), id="data_4_zero_byte"),
37+
pytest.param(Bytes(b"0xFF"), id="data_1_non_zero_byte"),
38+
pytest.param(Bytes(b"0x00FF"), id="data_1_zero_byte_1_non_zero_byte"),
39+
pytest.param(Bytes(b"0xFE00"), id="data_1_zero_byte_1_non_zero_byte_reversed"),
40+
pytest.param(Bytes(b"0x0102030405060708090A0B0C0D0E0F10"), id="data_set_1"),
41+
pytest.param(
42+
Bytes(b"0x0102030405060708090A0B0C0D0E0F101112131415161718191a1b1c1d1e1f20"),
43+
id="data_set_1",
44+
),
45+
pytest.param(
46+
Bytes(b"0x00010203040506000708090A0B0C0D0E0F10111200131415161718191a1b1c1d1e1f"),
47+
id="data_set_2",
48+
),
49+
pytest.param(
50+
Bytes(b"0x01020304050607080910111213141516171819202122232425262728293031"),
51+
id="data_set_31_bytes",
52+
),
53+
pytest.param(
54+
Bytes(b"0x000102030405060708090A0B0C0D0E0F101112131415161718191a1b1c1d1e1f"),
55+
id="data_set_32_bytes",
56+
),
57+
pytest.param(
58+
Bytes(b"0x010203040506070809101112131415161718192021222324252627282930313233"),
59+
id="data_set_33_bytes",
60+
),
61+
pytest.param(
62+
Bytes(b"0x000000000000000000000000000000000000000000000000000000000000000000"),
63+
id="data_set_33_empty_bytes",
64+
),
65+
pytest.param(
66+
Bytes(
67+
b"0x000000000000000000000000000000000000000000000000000000000000000000010203040506070809101112131415161718192021222324252627282930313233"
68+
),
69+
id="data_set_66_bytes_half_zeros",
70+
),
71+
],
72+
)
73+
@pytest.mark.parametrize(
74+
"access_list",
75+
[
76+
pytest.param([], id="access_list_empty"),
77+
pytest.param(
78+
[AccessList(address=1, storage_keys=[])],
79+
id="access_list_1_address_empty_keys",
80+
),
81+
pytest.param(
82+
[AccessList(address=1, storage_keys=[0x60A7])],
83+
id="access_list_1_address_1_keys",
84+
),
85+
pytest.param(
86+
[AccessList(address=1, storage_keys=[0x60A7, 0x60A8])],
87+
id="access_list_1_address_2_keys",
88+
),
89+
pytest.param(
90+
[
91+
AccessList(address=1, storage_keys=[]),
92+
AccessList(address=2, storage_keys=[]),
93+
],
94+
id="access_list_2_address_empty_keys",
95+
),
96+
pytest.param(
97+
[
98+
AccessList(address=1, storage_keys=[]),
99+
AccessList(address=2, storage_keys=[0x60A7]),
100+
],
101+
id="access_list_2_address_1_keys",
102+
),
103+
pytest.param(
104+
[
105+
AccessList(address=1, storage_keys=[0x60A7]),
106+
AccessList(address=2, storage_keys=[0x60A8]),
107+
],
108+
id="access_list_2_address_2_keys",
109+
),
110+
pytest.param(
111+
[
112+
AccessList(address=1, storage_keys=[0x60A7, 0x60A8]),
113+
AccessList(address=2, storage_keys=[]),
114+
],
115+
id="access_list_2_address_2_keys_inversion",
116+
),
117+
pytest.param(
118+
[
119+
AccessList(address=1, storage_keys=[0xCE11]),
120+
AccessList(address=2, storage_keys=[0x60A7]),
121+
*[
122+
AccessList(
123+
address=Address(i),
124+
storage_keys=[0x600D, 0x0BAD, 0x60A7, 0xBEEF],
125+
)
126+
for i in range(3, 13) # 3 to 12 inclusive (10 entries)
127+
],
128+
],
129+
id="access_list_12_address_42_keys",
130+
),
131+
],
132+
)
133+
@pytest.mark.parametrize(
134+
"below_intrinsic",
135+
[
136+
pytest.param(False),
137+
pytest.param(True, marks=pytest.mark.exception_test),
138+
],
139+
)
140+
def test_tx_intrinsic_gas(
141+
state_test: StateTestFiller,
142+
pre: Alloc,
143+
fork: Fork,
144+
data: Bytes,
145+
access_list: List[AccessList],
146+
below_intrinsic: bool,
147+
):
148+
"""Transaction intrinsic gas calculation on EIP2930."""
149+
intrinsic_gas_cost_calculator = fork.transaction_intrinsic_cost_calculator()
150+
intrinsic_gas_cost = intrinsic_gas_cost_calculator(calldata=data, access_list=access_list)
151+
152+
tx = Transaction(
153+
ty=0x1,
154+
chain_id=0x01,
155+
sender=pre.fund_eoa(),
156+
to=pre.deploy_contract(code=Op.SSTORE(0, Op.ADD(1, 1))),
157+
data=data,
158+
access_list=access_list,
159+
gas_limit=intrinsic_gas_cost + (-1 if below_intrinsic else 0),
160+
error=TransactionException.INTRINSIC_GAS_TOO_LOW if below_intrinsic else None,
161+
protected=True,
162+
)
163+
164+
state_test(env=Environment(), pre=pre, post={}, tx=tx)

0 commit comments

Comments
 (0)