Skip to content

Commit bbacd74

Browse files
authored
feat(tests): EIP-7981 reject in access-list-byte floor gap with exact-balance sender (#2880)
EIP-7981 charges every access-list byte (20 per address, 32 per storage key) at the floor token cost. A transaction whose `gas_limit` lies in `[Amsterdam_floor_without_AL_term, Amsterdam_floor)` must reject at pre-validate with `INTRINSIC_GAS_BELOW_FLOOR_GAS_COST`; an implementation that omits the access-list-byte term from its floor computes a smaller floor and accepts. This test pins `gas_limit` at the midpoint of that uplift gap for Type-1 and Type-2 transactions carrying 1000 / 2000 nonzero data bytes plus a 1-address / 10-storage-key access list. The sender is funded with exactly `gas_limit * gas_price`, so a buggy implementation cannot fall back to a silent "accept and execute" — any acceptance produces a divergent post-state. Complements `test_insufficient_gas_for_access_list` and `test_floor_cost_validation_with_access_list`, which exercise this boundary at `gas_limit = floor - 1` with default sender funding.
1 parent 76f336f commit bbacd74

1 file changed

Lines changed: 87 additions & 0 deletions

File tree

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
"""
2+
abstract: Tests for floor-boundary rejection with exact-balance funding in [EIP-7981: Increase Access List Cost](https://eips.ethereum.org/EIPS/eip-7981).
3+
""" # noqa: E501
4+
5+
import pytest
6+
from execution_testing import (
7+
AccessList,
8+
Address,
9+
Alloc,
10+
Bytes,
11+
Fork,
12+
Hash,
13+
StateTestFiller,
14+
Transaction,
15+
TransactionException,
16+
)
17+
18+
from .spec import ref_spec_7981
19+
20+
REFERENCE_SPEC_GIT_PATH = ref_spec_7981.git_path
21+
REFERENCE_SPEC_VERSION = ref_spec_7981.version
22+
23+
pytestmark = pytest.mark.valid_at("EIP7981")
24+
25+
26+
@pytest.mark.exception_test
27+
@pytest.mark.parametrize(
28+
"tx_type",
29+
[pytest.param(1, id="type_1"), pytest.param(2, id="type_2")],
30+
)
31+
@pytest.mark.parametrize(
32+
"nonzero_bytes",
33+
[
34+
pytest.param(1000, id="1000_nonzero_bytes"),
35+
pytest.param(2000, id="2000_nonzero_bytes"),
36+
],
37+
)
38+
def test_below_amsterdam_floor_with_access_list_exact_balance(
39+
state_test: StateTestFiller,
40+
pre: Alloc,
41+
fork: Fork,
42+
tx_type: int,
43+
nonzero_bytes: int,
44+
) -> None:
45+
"""Reject when gas_limit sits in EIP-7981 access-list-byte floor gap."""
46+
access_list = [
47+
AccessList(
48+
address=Address(1),
49+
storage_keys=[Hash(k) for k in range(10)],
50+
)
51+
]
52+
tx_data = Bytes(b"\x01" * nonzero_bytes)
53+
intrinsic_regular = fork.transaction_intrinsic_cost_calculator()(
54+
calldata=tx_data,
55+
access_list=access_list,
56+
return_cost_deducted_prior_execution=True,
57+
)
58+
floor_calc = fork.transaction_data_floor_cost_calculator()
59+
amsterdam_floor = floor_calc(data=tx_data, access_list=access_list)
60+
amsterdam_floor_no_al = floor_calc(data=tx_data)
61+
# Pin gas_limit inside the access-list-byte uplift gap so an
62+
# implementation that omits this term from its floor accepts.
63+
gas_limit = (amsterdam_floor_no_al + amsterdam_floor) // 2
64+
assert intrinsic_regular <= gas_limit < amsterdam_floor
65+
assert gas_limit >= amsterdam_floor_no_al
66+
67+
gas_price = 10
68+
sender = pre.fund_eoa(amount=gas_limit * gas_price)
69+
if tx_type == 1:
70+
fee_args: dict = {"gas_price": gas_price}
71+
else:
72+
fee_args = {
73+
"max_fee_per_gas": gas_price,
74+
"max_priority_fee_per_gas": 0,
75+
}
76+
tx = Transaction(
77+
ty=tx_type,
78+
sender=sender,
79+
to=pre.fund_eoa(amount=0),
80+
data=tx_data,
81+
gas_limit=gas_limit,
82+
access_list=access_list,
83+
error=TransactionException.INTRINSIC_GAS_BELOW_FLOOR_GAS_COST,
84+
**fee_args,
85+
)
86+
87+
state_test(pre=pre, post={}, tx=tx)

0 commit comments

Comments
 (0)