Skip to content

Commit 4a77afb

Browse files
authored
fix(tests): EIP-7623 update due to spec change (#1071)
* fix(tests): EIP-7623 update due to spec change * Add comments
1 parent 4891ac7 commit 4a77afb

File tree

4 files changed

+340
-169
lines changed

4 files changed

+340
-169
lines changed

docs/CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Release tarball changes:
2323
-[EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) set code of non-empty-storage account test ([#948](https://github.com/ethereum/execution-spec-tests/pull/948))
2424
-[EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) Remove delegation behavior of EXTCODE* ([#984](https://github.com/ethereum/execution-spec-tests/pull/984))
2525
-[EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) implement 7702 test ideas ([#981](https://github.com/ethereum/execution-spec-tests/pull/981))
26-
-[EIP-7623](https://eips.ethereum.org/EIPS/eip-7623) Increase calldata cost ([#1004](https://github.com/ethereum/execution-spec-tests/pull/1004))
26+
-[EIP-7623](https://eips.ethereum.org/EIPS/eip-7623) Increase calldata cost ([#1004](https://github.com/ethereum/execution-spec-tests/pull/1004), [#1071](https://github.com/ethereum/execution-spec-tests/pull/1071))
2727
- ✨ Add generic precompile-absence test ([#1036](https://github.com/ethereum/execution-spec-tests/pull/1036))
2828
- ✨ Add test for [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537) which uses the full discount table of G2 MSM ([#1038](https://github.com/ethereum/execution-spec-tests/pull/1038))
2929
- 🔀 Update EIP-7251 according to [spec updates](https://github.com/ethereum/EIPs/pull/9127) ([#1024](https://github.com/ethereum/execution-spec-tests/pull/1024)).

tests/prague/eip7623_increase_calldata_cost/conftest.py

+29-4
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,30 @@ def tx_gas_delta() -> int:
231231

232232

233233
@pytest.fixture
234-
def tx_intrinsic_gas_cost(
234+
def tx_intrinsic_gas_cost_before_execution(
235+
fork: Fork,
236+
tx_data: Bytes,
237+
access_list: List[AccessList] | None,
238+
authorization_list: List[AuthorizationTuple] | None,
239+
contract_creating_tx: bool,
240+
) -> int:
241+
"""
242+
Return the intrinsic gas cost that is applied before the execution start.
243+
244+
This value never includes the floor data gas cost.
245+
"""
246+
intrinsic_gas_cost_calculator = fork.transaction_intrinsic_cost_calculator()
247+
return intrinsic_gas_cost_calculator(
248+
calldata=tx_data,
249+
contract_creation=contract_creating_tx,
250+
access_list=access_list,
251+
authorization_list_or_count=authorization_list,
252+
return_cost_deducted_prior_execution=True,
253+
)
254+
255+
256+
@pytest.fixture
257+
def tx_intrinsic_gas_cost_including_floor_data_cost(
235258
fork: Fork,
236259
tx_data: Bytes,
237260
access_list: List[AccessList] | None,
@@ -242,7 +265,9 @@ def tx_intrinsic_gas_cost(
242265
Transaction intrinsic gas cost.
243266
244267
The calculated value takes into account the normal intrinsic gas cost and the floor data gas
245-
cost.
268+
cost if it is greater than the intrinsic gas cost.
269+
270+
In other words, this is the value that is required for the transaction to be valid.
246271
"""
247272
intrinsic_gas_cost_calculator = fork.transaction_intrinsic_cost_calculator()
248273
return intrinsic_gas_cost_calculator(
@@ -265,15 +290,15 @@ def tx_floor_data_cost(
265290

266291
@pytest.fixture
267292
def tx_gas_limit(
268-
tx_intrinsic_gas_cost: int,
293+
tx_intrinsic_gas_cost_including_floor_data_cost: int,
269294
tx_gas_delta: int,
270295
) -> int:
271296
"""
272297
Gas limit for the transaction.
273298
274299
The gas delta is added to the intrinsic gas cost to generate different test scenarios.
275300
"""
276-
return tx_intrinsic_gas_cost + tx_gas_delta
301+
return tx_intrinsic_gas_cost_including_floor_data_cost + tx_gas_delta
277302

278303

279304
@pytest.fixture

tests/prague/eip7623_increase_calldata_cost/test_execution_gas.py

+14-164
Original file line numberDiff line numberDiff line change
@@ -38,98 +38,8 @@ def data_test_type() -> DataTestType:
3838

3939
@pytest.fixture
4040
def authorization_refund() -> bool:
41-
"""
42-
Force the authority of the authorization tuple to be an existing authority in order
43-
to produce a refund.
44-
"""
45-
return True
46-
47-
48-
class TestGasRefunds:
49-
"""Test gas refunds with EIP-7623 active."""
50-
51-
@pytest.fixture
52-
def intrinsic_gas_data_floor_minimum_delta(self) -> int:
53-
"""
54-
In this test we reset a storage key to zero to induce a refund,
55-
but we need to make sure that the floor is higher than the gas
56-
used during execution in order for the refund to be applied to
57-
the floor.
58-
"""
59-
return 50_000
60-
61-
@pytest.fixture
62-
def to(
63-
self,
64-
pre: Alloc,
65-
) -> Address | None:
66-
"""Return a contract that when executed results in refunds due to storage clearing."""
67-
return pre.deploy_contract(Op.SSTORE(0, 0) + Op.STOP, storage={0: 1})
68-
69-
@pytest.fixture
70-
def refund(self, fork: Fork, ty: int) -> int:
71-
"""Return the refund gas of the transaction."""
72-
gas_costs = fork.gas_costs()
73-
refund = gas_costs.R_STORAGE_CLEAR
74-
if ty == 4:
75-
refund += gas_costs.R_AUTHORIZATION_EXISTING_AUTHORITY
76-
return refund
77-
78-
@pytest.mark.parametrize(
79-
"ty,protected,authorization_list",
80-
[
81-
pytest.param(0, False, None, id="type_0_unprotected"),
82-
pytest.param(0, True, None, id="type_0_protected"),
83-
pytest.param(1, True, None, id="type_1"),
84-
pytest.param(2, True, None, id="type_2"),
85-
pytest.param(
86-
3,
87-
True,
88-
None,
89-
id="type_3",
90-
),
91-
pytest.param(
92-
4,
93-
True,
94-
[Address(1)],
95-
id="type_4_with_authorization_refund",
96-
),
97-
],
98-
indirect=["authorization_list"],
99-
)
100-
@pytest.mark.parametrize(
101-
"tx_gas_delta",
102-
[
103-
# Test with exact gas and extra gas, to verify that the refund is correctly applied up
104-
# to the floor data cost.
105-
pytest.param(1, id="extra_gas"),
106-
pytest.param(0, id="exact_gas"),
107-
],
108-
)
109-
def test_gas_refunds_from_data_floor(
110-
self,
111-
state_test: StateTestFiller,
112-
pre: Alloc,
113-
tx: Transaction,
114-
tx_floor_data_cost: int,
115-
refund: int,
116-
) -> None:
117-
"""
118-
Test gas refunds deducted from the data floor.
119-
120-
I.e. the used gas by the intrinsic gas cost plus the execution cost is less than the data
121-
floor, hence data floor is used, and then the gas refunds are applied to the data floor.
122-
"""
123-
tx.expected_receipt = TransactionReceipt(gas_used=tx_floor_data_cost - refund)
124-
state_test(
125-
pre=pre,
126-
post={
127-
tx.to: {
128-
"storage": {0: 0}, # Verify storage was cleared
129-
}
130-
},
131-
tx=tx,
132-
)
41+
"""Disable the refunds on these tests (see ./test_refunds.py)."""
42+
return False
13343

13444

13545
class TestGasConsumption:
@@ -148,47 +58,22 @@ def to(
14858
"""Return a contract that consumes all gas when executed by calling an invalid opcode."""
14959
return pre.deploy_contract(Op.INVALID)
15060

151-
@pytest.fixture
152-
def refund(
153-
self,
154-
fork: Fork,
155-
ty: int,
156-
authorization_refund: bool,
157-
) -> int:
158-
"""Return the refund gas of the transaction."""
159-
gas_costs = fork.gas_costs()
160-
refund = 0
161-
if ty == 4 and authorization_refund:
162-
refund += gas_costs.R_AUTHORIZATION_EXISTING_AUTHORITY
163-
return refund
164-
16561
@pytest.mark.parametrize(
16662
"ty,protected,authorization_list",
16763
[
16864
pytest.param(0, False, None, id="type_0_unprotected"),
16965
pytest.param(0, True, None, id="type_0_protected"),
17066
pytest.param(1, True, None, id="type_1"),
17167
pytest.param(2, True, None, id="type_2"),
172-
pytest.param(
173-
3,
174-
True,
175-
None,
176-
id="type_3",
177-
),
178-
pytest.param(
179-
4,
180-
True,
181-
[Address(1)],
182-
id="type_4_with_authorization_refund",
183-
),
68+
pytest.param(3, True, None, id="type_3"),
69+
pytest.param(4, True, [Address(1)], id="type_4"),
18470
],
18571
indirect=["authorization_list"],
18672
)
18773
@pytest.mark.parametrize(
18874
"tx_gas_delta",
18975
[
190-
# Test with exact gas and extra gas, to verify that the refund is correctly applied
191-
# to the full consumed execution gas.
76+
# Test with exact gas and extra gas.
19277
pytest.param(1, id="extra_gas"),
19378
pytest.param(0, id="exact_gas"),
19479
],
@@ -198,10 +83,9 @@ def test_full_gas_consumption(
19883
state_test: StateTestFiller,
19984
pre: Alloc,
20085
tx: Transaction,
201-
refund: int,
20286
) -> None:
20387
"""Test executing a transaction that fully consumes its execution gas allocation."""
204-
tx.expected_receipt = TransactionReceipt(gas_used=tx.gas_limit - refund)
88+
tx.expected_receipt = TransactionReceipt(gas_used=tx.gas_limit)
20589
state_test(
20690
pre=pre,
20791
post={},
@@ -217,20 +101,6 @@ def contract_creating_tx(self) -> bool:
217101
"""Use a constant in order to avoid circular fixture dependencies."""
218102
return False
219103

220-
@pytest.fixture
221-
def refund(
222-
self,
223-
fork: Fork,
224-
ty: int,
225-
authorization_refund: bool,
226-
) -> int:
227-
"""Return the refund gas of the transaction."""
228-
gas_costs = fork.gas_costs()
229-
refund = 0
230-
if ty == 4 and authorization_refund:
231-
refund += gas_costs.R_AUTHORIZATION_EXISTING_AUTHORITY
232-
return refund
233-
234104
@pytest.fixture
235105
def to(
236106
self,
@@ -258,33 +128,14 @@ def to(
258128
return pre.deploy_contract((Op.JUMPDEST * (execution_gas - 1)) + Op.STOP)
259129

260130
@pytest.mark.parametrize(
261-
"ty,protected,authorization_list,authorization_refund",
131+
"ty,protected,authorization_list",
262132
[
263-
pytest.param(0, False, None, False, id="type_0_unprotected"),
264-
pytest.param(0, True, None, False, id="type_0_protected"),
265-
pytest.param(1, True, None, False, id="type_1"),
266-
pytest.param(2, True, None, False, id="type_2"),
267-
pytest.param(
268-
3,
269-
True,
270-
None,
271-
False,
272-
id="type_3",
273-
),
274-
pytest.param(
275-
4,
276-
True,
277-
[Address(1)],
278-
False,
279-
id="type_4",
280-
),
281-
pytest.param(
282-
4,
283-
True,
284-
[Address(1)],
285-
True,
286-
id="type_4_with_authorization_refund",
287-
),
133+
pytest.param(0, False, None, id="type_0_unprotected"),
134+
pytest.param(0, True, None, id="type_0_protected"),
135+
pytest.param(1, True, None, id="type_1"),
136+
pytest.param(2, True, None, id="type_2"),
137+
pytest.param(3, True, None, id="type_3"),
138+
pytest.param(4, True, [Address(1)], id="type_4"),
288139
],
289140
indirect=["authorization_list"],
290141
)
@@ -302,10 +153,9 @@ def test_gas_consumption_below_data_floor(
302153
pre: Alloc,
303154
tx: Transaction,
304155
tx_floor_data_cost: int,
305-
refund: int,
306156
) -> None:
307157
"""Test executing a transaction that almost consumes the floor data cost."""
308-
tx.expected_receipt = TransactionReceipt(gas_used=tx_floor_data_cost - refund)
158+
tx.expected_receipt = TransactionReceipt(gas_used=tx_floor_data_cost)
309159
state_test(
310160
pre=pre,
311161
post={},

0 commit comments

Comments
 (0)