Skip to content

test_floor_cost_across_amsterdam_transition()

Documentation for tests/amsterdam/eip7976_increase_calldata_floor_cost/test_fork_transition.py::test_floor_cost_across_amsterdam_transition@26332146.

Generate fixtures for these test cases for Amsterdam with:

fill -v tests/amsterdam/eip7976_increase_calldata_floor_cost/test_fork_transition.py::test_floor_cost_across_amsterdam_transition --fork Amsterdam

Pin the EIP-7976 floor increase across the Amsterdam boundary.

The same data-heavy transaction to an existing EOA (no EVM execution) is sent in a pre-fork block and a post-fork block with the gas limit pinned to the fork-appropriate floor, so the billed gas equals the calldata floor exactly on both sides. The zero-byte arm discriminates the uniform token counting (zero bytes lose their floor discount); the non-zero arm discriminates the per-token price alone.

The per-fork floor returned by the calculator is also checked against a hand-derived value built from each fork's gas constants, so a calculator regression fails here with a clear message rather than only as a downstream balance mismatch.

Source code in tests/amsterdam/eip7976_increase_calldata_floor_cost/test_fork_transition.py
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
@EIPChecklist.GasCostChanges.Test.ForkTransition.Before()
@EIPChecklist.GasCostChanges.Test.ForkTransition.After()
@pytest.mark.parametrize(
    "data",
    [
        pytest.param(ALL_ZERO_DATA, id="all_zero_bytes"),
        pytest.param(ALL_NONZERO_DATA, id="all_nonzero_bytes"),
    ],
)
def test_floor_cost_across_amsterdam_transition(
    blockchain_test: BlockchainTestFiller,
    pre: Alloc,
    fork: TransitionFork,
    data: bytes,
) -> None:
    """
    Pin the EIP-7976 floor increase across the Amsterdam boundary.

    The same data-heavy transaction to an existing EOA (no EVM
    execution) is sent in a pre-fork block and a post-fork block with
    the gas limit pinned to the fork-appropriate floor, so the billed
    gas equals the calldata floor exactly on both sides. The zero-byte
    arm discriminates the uniform token counting (zero bytes lose their
    floor discount); the non-zero arm discriminates the per-token price
    alone.

    The per-fork floor returned by the calculator is also checked
    against a hand-derived value built from each fork's gas constants,
    so a calculator regression fails here with a clear message rather
    than only as a downstream balance mismatch.
    """
    gas_price = 1_000_000_000
    target = pre.fund_eoa(amount=1)

    expected_pre, expected_post = expected_floors(fork, data)

    timestamps = [PRE_FORK_TIMESTAMP, POST_FORK_TIMESTAMP]
    expected_floors_per_block = [expected_pre, expected_post]
    blocks = []
    post: dict[Address, Account] = {}

    for timestamp, expected_floor in zip(
        timestamps, expected_floors_per_block, strict=True
    ):
        sub_fork = fork.fork_at(timestamp=timestamp)
        floor = sub_fork.transaction_data_floor_cost_calculator()(
            data=data,
            recipient_type=RecipientType.EOA,
        )
        assert floor == expected_floor, (
            f"floor at timestamp {timestamp} ({sub_fork}) is {floor}, "
            f"expected {expected_floor}"
        )
        # The floor must dominate the standard-side intrinsic so the
        # transaction is billed exactly the floor.
        intrinsic = sub_fork.transaction_intrinsic_cost_calculator()(
            calldata=data,
            recipient_type=RecipientType.EOA,
            return_cost_deducted_prior_execution=True,
        )
        assert floor > intrinsic, (
            f"floor {floor} does not dominate intrinsic {intrinsic} at "
            f"timestamp {timestamp} ({sub_fork})"
        )

        sender_initial_balance = 10**18
        sender = pre.fund_eoa(sender_initial_balance)

        # The recipient is an EOA, so no EVM bytecode runs and the
        # billed gas is exactly the floor; the gas limit is pinned to
        # the floor, leaving no buffer.
        tx = Transaction(
            sender=sender,
            to=target,
            data=data,
            gas_limit=floor,
            gas_price=gas_price,
            expected_receipt=TransactionReceipt(cumulative_gas_used=floor),
        )
        blocks.append(Block(timestamp=timestamp, txs=[tx]))

        post[sender] = Account(
            nonce=1,
            balance=sender_initial_balance - floor * gas_price,
        )

    blockchain_test(pre=pre, blocks=blocks, post=post)

Parametrized Test Cases

This test generates 2 parametrized test cases across 1 fork.