Skip to content

Commit f2255ce

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

File tree

5 files changed

+201
-3734
lines changed

5 files changed

+201
-3734
lines changed

converted-ethereum-tests.txt

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
([#1535](https://github.com/ethereum/execution-spec-tests/pull/1535))
2+
GeneralStateTests/stEIP1559/intrinsicCancun.json
3+
BlockchainTests/ValidBlocks/bcEIP1559/intrinsic.json
4+
BlockchainTests/ValidBlocks/bcEIP1559/intrinsicTip.json
5+
BlockchainTests/InvalidBlocks/bcEIP1559/intrinsicOrFailCancun.json
6+
17
([#1056](https://github.com/ethereum/execution-spec-tests/pull/1056))
28
GeneralStateTests/VMTests/vmTests/calldatacopy.json
39

+31
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
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, London
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+
tx_intrinsic_gas_data_vectors = [
31+
pytest.param(Bytes(b""), id="data_empty"),
32+
pytest.param(Bytes(b"0x00"), id="data_1_zero_byte"),
33+
pytest.param(Bytes(b"0x00000000"), id="data_4_zero_byte"),
34+
pytest.param(Bytes(b"0xFF"), id="data_1_non_zero_byte"),
35+
pytest.param(Bytes(b"0x00FF"), id="data_1_zero_byte_1_non_zero_byte"),
36+
pytest.param(Bytes(b"0xFE00"), id="data_1_zero_byte_1_non_zero_byte_reversed"),
37+
pytest.param(Bytes(b"0x0102030405060708090A0B0C0D0E0F10"), id="data_set_1"),
38+
pytest.param(
39+
Bytes(b"0x0102030405060708090A0B0C0D0E0F101112131415161718191a1b1c1d1e1f20"),
40+
id="data_set_1",
41+
),
42+
pytest.param(
43+
Bytes(b"0x00010203040506000708090A0B0C0D0E0F10111200131415161718191a1b1c1d1e1f"),
44+
id="data_set_2",
45+
),
46+
pytest.param(
47+
Bytes(b"0x01020304050607080910111213141516171819202122232425262728293031"),
48+
id="data_set_31_bytes",
49+
),
50+
pytest.param(
51+
Bytes(b"0x000102030405060708090A0B0C0D0E0F101112131415161718191a1b1c1d1e1f"),
52+
id="data_set_32_bytes",
53+
),
54+
pytest.param(
55+
Bytes(b"0x010203040506070809101112131415161718192021222324252627282930313233"),
56+
id="data_set_33_bytes",
57+
),
58+
pytest.param(
59+
Bytes(b"0x000000000000000000000000000000000000000000000000000000000000000000"),
60+
id="data_set_33_empty_bytes",
61+
),
62+
pytest.param(
63+
Bytes(
64+
b"0x000000000000000000000000000000000000000000000000000000000000000000010203040506070809101112131415161718192021222324252627282930313233"
65+
),
66+
id="data_set_66_bytes_half_zeros",
67+
),
68+
]
69+
70+
tx_intrinsic_gas_access_list_vectors = [
71+
pytest.param([], id="access_list_empty"),
72+
pytest.param(
73+
[AccessList(address=1, storage_keys=[])],
74+
id="access_list_1_address_empty_keys",
75+
),
76+
pytest.param(
77+
[AccessList(address=1, storage_keys=[0x60A7])],
78+
id="access_list_1_address_1_keys",
79+
),
80+
pytest.param(
81+
[AccessList(address=1, storage_keys=[0x60A7, 0x60A8])],
82+
id="access_list_1_address_2_keys",
83+
),
84+
pytest.param(
85+
[
86+
AccessList(address=1, storage_keys=[]),
87+
AccessList(address=2, storage_keys=[]),
88+
],
89+
id="access_list_2_address_empty_keys",
90+
),
91+
pytest.param(
92+
[
93+
AccessList(address=1, storage_keys=[]),
94+
AccessList(address=2, storage_keys=[0x60A7]),
95+
],
96+
id="access_list_2_address_1_keys",
97+
),
98+
pytest.param(
99+
[
100+
AccessList(address=1, storage_keys=[0x60A7]),
101+
AccessList(address=2, storage_keys=[0x60A8]),
102+
],
103+
id="access_list_2_address_2_keys",
104+
),
105+
pytest.param(
106+
[
107+
AccessList(address=1, storage_keys=[0x60A7, 0x60A8]),
108+
AccessList(address=2, storage_keys=[]),
109+
],
110+
id="access_list_2_address_2_keys_inversion",
111+
),
112+
pytest.param(
113+
[
114+
AccessList(address=1, storage_keys=[0xCE11]),
115+
AccessList(address=2, storage_keys=[0x60A7]),
116+
*[
117+
AccessList(
118+
address=Address(i),
119+
storage_keys=[0x600D, 0x0BAD, 0x60A7, 0xBEEF],
120+
)
121+
for i in range(3, 13) # 3 to 12 inclusive (10 entries)
122+
],
123+
],
124+
id="access_list_12_address_42_keys",
125+
),
126+
]
127+
128+
129+
@pytest.mark.parametrize("data", tx_intrinsic_gas_data_vectors)
130+
@pytest.mark.parametrize("access_list", tx_intrinsic_gas_access_list_vectors)
131+
@pytest.mark.parametrize(
132+
"below_intrinsic",
133+
[
134+
pytest.param(False),
135+
pytest.param(True, marks=pytest.mark.exception_test),
136+
],
137+
)
138+
def test_tx_intrinsic_gas(
139+
state_test: StateTestFiller,
140+
pre: Alloc,
141+
fork: Fork,
142+
data: Bytes,
143+
access_list: List[AccessList],
144+
below_intrinsic: bool,
145+
):
146+
"""Transaction intrinsic gas calculation on EIP2930."""
147+
intrinsic_gas_cost_calculator = fork.transaction_intrinsic_cost_calculator()
148+
intrinsic_gas_cost = intrinsic_gas_cost_calculator(calldata=data, access_list=access_list)
149+
150+
tx = Transaction(
151+
ty=0x1 if fork < London else 0x2,
152+
max_fee_per_gas=None if fork < London else 1000,
153+
max_priority_fee_per_gas=None if fork < London else 200,
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)