Skip to content

Commit 6493b33

Browse files
committed
refactor(tests): EIP-7623: Add gas-used check to tests
1 parent ab2a487 commit 6493b33

File tree

2 files changed

+110
-64
lines changed

2 files changed

+110
-64
lines changed

tests/prague/eip7623_increase_calldata_cost/conftest.py

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616
Hash,
1717
Transaction,
1818
TransactionException,
19+
add_kzg_version,
1920
)
2021
from ethereum_test_tools import Opcodes as Op
2122

23+
from ...cancun.eip4844_blobs.spec import Spec as EIP_4844_Spec
2224
from .helpers import DataTestType, find_floor_cost_threshold
2325

2426

@@ -65,7 +67,7 @@ def access_list() -> List[AccessList] | None:
6567

6668

6769
@pytest.fixture
68-
def authorization_existing_authority() -> bool:
70+
def authorization_refund() -> bool:
6971
"""Return whether the transaction has an existing authority in the authorization list."""
7072
return False
7173

@@ -74,7 +76,7 @@ def authorization_existing_authority() -> bool:
7476
def authorization_list(
7577
request: pytest.FixtureRequest,
7678
pre: Alloc,
77-
authorization_existing_authority: bool,
79+
authorization_refund: bool,
7880
) -> List[AuthorizationTuple] | None:
7981
"""
8082
Authorization-list for the transaction.
@@ -88,17 +90,22 @@ def authorization_list(
8890
if request.param is None:
8991
return None
9092
return [
91-
AuthorizationTuple(
92-
signer=pre.fund_eoa(1 if authorization_existing_authority else 0), address=address
93-
)
93+
AuthorizationTuple(signer=pre.fund_eoa(1 if authorization_refund else 0), address=address)
9494
for address in request.param
9595
]
9696

9797

9898
@pytest.fixture
99-
def blob_versioned_hashes() -> Sequence[Hash] | None:
99+
def blob_versioned_hashes(ty: int) -> Sequence[Hash] | None:
100100
"""Versioned hashes for the transaction."""
101-
return None
101+
return (
102+
add_kzg_version(
103+
[Hash(1)],
104+
EIP_4844_Spec.BLOB_COMMITMENT_VERSION_KZG,
105+
)
106+
if ty == 3
107+
else None
108+
)
102109

103110

104111
@pytest.fixture
@@ -224,34 +231,51 @@ def tx_gas_delta() -> int:
224231

225232

226233
@pytest.fixture
227-
def tx_gas(
234+
def tx_intrinsic_gas_cost(
228235
fork: Fork,
229236
tx_data: Bytes,
230237
access_list: List[AccessList] | None,
231238
authorization_list: List[AuthorizationTuple] | None,
232239
contract_creating_tx: bool,
233-
tx_gas_delta: int,
234240
) -> int:
235241
"""
236-
Gas limit for the transaction.
242+
Transaction intrinsic gas cost.
237243
238244
The calculated value takes into account the normal intrinsic gas cost and the floor data gas
239245
cost.
240-
241-
The gas delta is added to the intrinsic gas cost to generate different test scenarios.
242246
"""
243247
intrinsic_gas_cost_calculator = fork.transaction_intrinsic_cost_calculator()
244-
return (
245-
intrinsic_gas_cost_calculator(
246-
calldata=tx_data,
247-
contract_creation=contract_creating_tx,
248-
access_list=access_list,
249-
authorization_list_or_count=authorization_list,
250-
)
251-
+ tx_gas_delta
248+
return intrinsic_gas_cost_calculator(
249+
calldata=tx_data,
250+
contract_creation=contract_creating_tx,
251+
access_list=access_list,
252+
authorization_list_or_count=authorization_list,
252253
)
253254

254255

256+
@pytest.fixture
257+
def tx_floor_data_cost(
258+
fork: Fork,
259+
tx_data: Bytes,
260+
) -> int:
261+
"""Floor data cost for the given transaction data."""
262+
fork_data_floor_cost_calculator = fork.transaction_data_floor_cost_calculator()
263+
return fork_data_floor_cost_calculator(data=tx_data)
264+
265+
266+
@pytest.fixture
267+
def tx_gas_limit(
268+
tx_intrinsic_gas_cost: int,
269+
tx_gas_delta: int,
270+
) -> int:
271+
"""
272+
Gas limit for the transaction.
273+
274+
The gas delta is added to the intrinsic gas cost to generate different test scenarios.
275+
"""
276+
return tx_intrinsic_gas_cost + tx_gas_delta
277+
278+
255279
@pytest.fixture
256280
def tx_error(tx_gas_delta: int) -> TransactionException | None:
257281
"""Transaction error, only expected if the gas delta is negative."""
@@ -268,7 +292,7 @@ def tx(
268292
access_list: List[AccessList] | None,
269293
authorization_list: List[AuthorizationTuple] | None,
270294
blob_versioned_hashes: Sequence[Hash] | None,
271-
tx_gas: int,
295+
tx_gas_limit: int,
272296
tx_error: TransactionException | None,
273297
) -> Transaction:
274298
"""Create the transaction used in each test."""
@@ -280,7 +304,7 @@ def tx(
280304
protected=protected,
281305
access_list=access_list,
282306
authorization_list=authorization_list,
283-
gas_limit=tx_gas,
307+
gas_limit=tx_gas_limit,
284308
blob_versioned_hashes=blob_versioned_hashes,
285309
error=tx_error,
286310
)

tests/prague/eip7623_increase_calldata_cost/test_execution_gas.py

Lines changed: 64 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,12 @@
1414
Alloc,
1515
AuthorizationTuple,
1616
Bytes,
17-
Hash,
1817
StateTestFiller,
1918
Transaction,
20-
add_kzg_version,
19+
TransactionReceipt,
2120
)
2221
from ethereum_test_tools import Opcodes as Op
2322

24-
from ...cancun.eip4844_blobs.spec import Spec as EIP_4844_Spec
2523
from .helpers import DataTestType
2624
from .spec import ref_spec_7623
2725

@@ -39,7 +37,7 @@ def data_test_type() -> DataTestType:
3937

4038

4139
@pytest.fixture
42-
def authorization_existing_authority() -> bool:
40+
def authorization_refund() -> bool:
4341
"""
4442
Force the authority of the authorization tuple to be an existing authority in order
4543
to produce a refund.
@@ -68,27 +66,31 @@ def to(
6866
"""Return a contract that when executed results in refunds due to storage clearing."""
6967
return pre.deploy_contract(Op.SSTORE(0, 0) + Op.STOP, storage={0: 1})
7068

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+
7178
@pytest.mark.parametrize(
72-
"ty,protected,blob_versioned_hashes,authorization_list",
79+
"ty,protected,authorization_list",
7380
[
74-
pytest.param(0, False, None, None, id="type_0_unprotected"),
75-
pytest.param(0, True, None, None, id="type_0_protected"),
76-
pytest.param(1, True, None, None, id="type_1"),
77-
pytest.param(2, True, None, None, id="type_2"),
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"),
7885
pytest.param(
7986
3,
8087
True,
81-
add_kzg_version(
82-
[Hash(1)],
83-
EIP_4844_Spec.BLOB_COMMITMENT_VERSION_KZG,
84-
),
8588
None,
8689
id="type_3",
8790
),
8891
pytest.param(
8992
4,
9093
True,
91-
None,
9294
[Address(1)],
9395
id="type_4_with_authorization_refund",
9496
),
@@ -109,13 +111,16 @@ def test_gas_refunds_from_data_floor(
109111
state_test: StateTestFiller,
110112
pre: Alloc,
111113
tx: Transaction,
114+
tx_floor_data_cost: int,
115+
refund: int,
112116
) -> None:
113117
"""
114118
Test gas refunds deducted from the data floor.
115119
116120
I.e. the used gas by the intrinsic gas cost plus the execution cost is less than the data
117121
floor, hence data floor is used, and then the gas refunds are applied to the data floor.
118122
"""
123+
tx.expected_receipt = TransactionReceipt(gas_used=tx_floor_data_cost - refund)
119124
state_test(
120125
pre=pre,
121126
post={
@@ -143,27 +148,36 @@ def to(
143148
"""Return a contract that consumes all gas when executed by calling an invalid opcode."""
144149
return pre.deploy_contract(Op.INVALID)
145150

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+
146165
@pytest.mark.parametrize(
147-
"ty,protected,blob_versioned_hashes,authorization_list",
166+
"ty,protected,authorization_list",
148167
[
149-
pytest.param(0, False, None, None, id="type_0_unprotected"),
150-
pytest.param(0, True, None, None, id="type_0_protected"),
151-
pytest.param(1, True, None, None, id="type_1"),
152-
pytest.param(2, True, None, None, id="type_2"),
168+
pytest.param(0, False, None, id="type_0_unprotected"),
169+
pytest.param(0, True, None, id="type_0_protected"),
170+
pytest.param(1, True, None, id="type_1"),
171+
pytest.param(2, True, None, id="type_2"),
153172
pytest.param(
154173
3,
155174
True,
156-
add_kzg_version(
157-
[Hash(1)],
158-
EIP_4844_Spec.BLOB_COMMITMENT_VERSION_KZG,
159-
),
160175
None,
161176
id="type_3",
162177
),
163178
pytest.param(
164179
4,
165180
True,
166-
None,
167181
[Address(1)],
168182
id="type_4_with_authorization_refund",
169183
),
@@ -184,8 +198,10 @@ def test_full_gas_consumption(
184198
state_test: StateTestFiller,
185199
pre: Alloc,
186200
tx: Transaction,
201+
refund: int,
187202
) -> None:
188203
"""Test executing a transaction that fully consumes its execution gas allocation."""
204+
tx.expected_receipt = TransactionReceipt(gas_used=tx.gas_limit - refund)
189205
state_test(
190206
pre=pre,
191207
post={},
@@ -201,6 +217,20 @@ def contract_creating_tx(self) -> bool:
201217
"""Use a constant in order to avoid circular fixture dependencies."""
202218
return False
203219

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+
204234
@pytest.fixture
205235
def to(
206236
self,
@@ -209,19 +239,14 @@ def to(
209239
tx_data: Bytes,
210240
access_list: List[AccessList] | None,
211241
authorization_list: List[AuthorizationTuple] | None,
242+
tx_floor_data_cost: int,
212243
) -> Address | None:
213244
"""
214245
Return a contract that consumes almost all the gas before reaching the
215246
floor data cost.
216247
"""
217248
intrinsic_gas_cost_calculator = fork.transaction_intrinsic_cost_calculator()
218-
data_floor = intrinsic_gas_cost_calculator(
219-
calldata=tx_data,
220-
contract_creation=False,
221-
access_list=access_list,
222-
authorization_list_or_count=authorization_list,
223-
)
224-
execution_gas = data_floor - intrinsic_gas_cost_calculator(
249+
execution_gas = tx_floor_data_cost - intrinsic_gas_cost_calculator(
225250
calldata=tx_data,
226251
contract_creation=False,
227252
access_list=access_list,
@@ -233,35 +258,29 @@ def to(
233258
return pre.deploy_contract((Op.JUMPDEST * (execution_gas - 1)) + Op.STOP)
234259

235260
@pytest.mark.parametrize(
236-
"ty,protected,blob_versioned_hashes,authorization_list,authorization_existing_authority",
261+
"ty,protected,authorization_list,authorization_refund",
237262
[
238-
pytest.param(0, False, None, None, False, id="type_0_unprotected"),
239-
pytest.param(0, True, None, None, False, id="type_0_protected"),
240-
pytest.param(1, True, None, None, False, id="type_1"),
241-
pytest.param(2, True, None, None, False, id="type_2"),
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"),
242267
pytest.param(
243268
3,
244269
True,
245-
add_kzg_version(
246-
[Hash(1)],
247-
EIP_4844_Spec.BLOB_COMMITMENT_VERSION_KZG,
248-
),
249270
None,
250271
False,
251272
id="type_3",
252273
),
253274
pytest.param(
254275
4,
255276
True,
256-
None,
257277
[Address(1)],
258278
False,
259279
id="type_4",
260280
),
261281
pytest.param(
262282
4,
263283
True,
264-
None,
265284
[Address(1)],
266285
True,
267286
id="type_4_with_authorization_refund",
@@ -282,8 +301,11 @@ def test_gas_consumption_below_data_floor(
282301
state_test: StateTestFiller,
283302
pre: Alloc,
284303
tx: Transaction,
304+
tx_floor_data_cost: int,
305+
refund: int,
285306
) -> None:
286307
"""Test executing a transaction that almost consumes the floor data cost."""
308+
tx.expected_receipt = TransactionReceipt(gas_used=tx_floor_data_cost - refund)
287309
state_test(
288310
pre=pre,
289311
post={},

0 commit comments

Comments
 (0)